CH Round #17-C

这个算是一个技能点吧,不点不会,点了就没什么了。懒得写看书吧书上的1应该是0。。。

我又回来了太懒了不想翻书还是写写吧

必须边的判定条件:该边流量为0且两端的点在残余网络不在同一个联通分量

可行边的判定条件:该边流量为0或两端的点在残余网络在同一个联通分量

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=(<<); struct node
{
int x,y,c,id,next,other;
}a[];int len,last[];
void ins(int x,int y,int c,int id)
{
int k1,k2; len++;k1=len;
a[len].x=x;a[len].y=y;a[len].c=c;a[len].id=id;
a[len].next=last[x];last[x]=len; len++;k2=len;
a[len].x=y;a[len].y=x;a[len].c=;a[len].id=-;
a[len].next=last[y];last[y]=len; a[k1].other=k2;
a[k2].other=k1;
}
int st,ed;
int h[],list[];
bool bt_h()
{
int head=,tail=;list[]=st;
memset(h,,sizeof(h));h[st]=;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==&&a[k].c>)
{
h[y]=h[x]+;
list[tail++]=y;
}
}
head++;
}
if(h[ed]==)return false;
return true;
}
int findflow(int x,int f)
{
if(x==ed)return f;
int s=;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(a[k].c>&&h[y]==h[x]+&&f>s)
{
int t=findflow(y,min(a[k].c,f-s));
s+=t;a[k].c-=t;a[a[k].other].c+=t;
}
}
if(s==)h[x]=;
return s;
} //------------------dicnic---------------------- bool b[];
struct enode
{
int x,y,id,next;
}e[];int elen,elast[];
void eins(int x,int y,int id)
{
elen++;
e[elen].x=x;e[elen].y=y;e[elen].id=id;
e[elen].next=elast[x];elast[x]=elen;
}
int z,dfn[],low[];
int top,sta[];bool v[];
int cnt,bel[];
void SCC(int x)
{
dfn[x]=low[x]=++z;
sta[++top]=x;v[x]=true;
for(int k=elast[x];k;k=e[k].next)
{
int y=e[k].y;
if(dfn[y]==)
{
SCC(y);
low[x]=min(low[x],low[y]);
}
else if(v[y]==true)
low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x])
{
int k;cnt++;
do
{
k=sta[top];top--;
v[k]=false;
bel[k]=cnt;
}while(k!=x);
}
} int aslen,as[];
int main()
{
int n,m,T,x,y;
scanf("%d%d%d",&n,&m,&T);
st=n+m+,ed=n+m+;
len=;memset(last,,sizeof(last));
for(int i=;i<=T;i++)
scanf("%d%d",&x,&y), ins(x,y+n,,i);
for(int i=;i<=n;i++)ins(st,i,,-);
for(int i=;i<=m;i++)ins(i+n,ed,,-); int ans=;
while(bt_h())
{
ans+=findflow(st,inf);
} //----------------------------------------- elen=;memset(elast,,sizeof(elast));
memset(b,true,sizeof(b));
for(int i=;i<=len;i++)
{
if(a[i].c==&&a[i].y>n&&a[i].x!=st&&a[i].y!=ed)b[a[i].id]=false;
if(a[i].c==)
eins(a[i].x,a[i].y,a[i].id);
} z=,top=,cnt=;
for(int i=;i<=n+m+;i++)
if(dfn[i]==)SCC(i); for(int i=;i<=elen;i++)
if(bel[e[i].x]==bel[e[i].y])b[e[i].id]=false; aslen=;
for(int i=;i<=T;i++)
if(b[i]==true)as[++aslen]=i;
printf("%d\n",aslen);
for(int i=;i<aslen;i++)printf("%d ",as[i]);
if(aslen!=)printf("%d\n",as[aslen]);
return ;
}

舞动的夜晚

poj1966 不难。拆点,删除一个点相当于把他的两个点之间的边割掉。有趣的是,这题枚举起始点和结束点,意在把这两个点分在不同的集合,使得图不联通。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=(<<); struct node
{
int x,y,c,next,other;
}a[],e[];int len,last[],elen,elast[];
void ins(int x,int y,int c)
{
int k1,k2; len++;k1=len;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len; len++;k2=len;
a[len].x=y;a[len].y=x;a[len].c=;
a[len].next=last[y];last[y]=len; a[k1].other=k2;
a[k2].other=k1;
}
int st,ed;
int h[],list[];
bool bt_h()
{
int head=,tail=;list[]=st;
memset(h,,sizeof(h));h[st]=;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==&&a[k].c>)
{
h[y]=h[x]+;
list[tail++]=y;
}
}
head++;
}
if(h[ed]==)return false;
return true;
}
int findflow(int x,int f)
{
if(x==ed)return f;
int s=;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(a[k].c>&&h[y]==h[x]+&&f>s)
{
int t=findflow(y,min(a[k].c,f-s));
s+=t;a[k].c-=t;a[a[k].other].c+=t;
}
}
if(s==)h[x]=;
return s;
} char ch;
void sc(int &x,int &y)
{
ch=getchar();
while(ch!='(')ch=getchar();
scanf("%d",&x);x++;
ch=getchar();
while(ch!=',')ch=getchar();
scanf("%d",&y);y++;
ch=getchar();
while(ch!=')')ch=getchar();
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
len=;memset(last,,sizeof(last));
for(int i=;i<=n;i++)ins(i,i+n,);
for(int i=;i<=m;i++)
{
int x,y;sc(x,y);
ins(x+n,y,inf);ins(y+n,x,inf);
} memcpy(e,a,sizeof(e));
elen=len;memcpy(elast,last,sizeof(elast));
int mmin=inf;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(i!=j)
{
memcpy(a,e,sizeof(a));
len=elen;memcpy(last,elast,sizeof(last)); st=i+n,ed=j;
int ans=;
while(bt_h())
{
ans+=findflow(st,inf);
}
mmin=min(ans,mmin);
}
if(mmin==inf)printf("%d\n",n);
else printf("%d\n",mmin);
}
return ;
}

poj1966

poj3422 算是套路题吧,拆点后对于一个点的自连,连一条流量为1,费用为点权的边,连一条流量为K-1,费用为0的边。开始我从1,1的出边为起始到n,n的入边,问题在于无法控制只跑K次。天真的我还写了while(K--&&spfa())事实证明这样错得一批

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=(<<); struct node
{
int x,y,c,d,next,other;
}a[];int len,last[];
void ins(int x,int y,int c,int d)
{
int k1,k2; len++;k1=len;
a[len].x=x;a[len].y=y;a[len].c=c;a[len].d=d;
a[len].next=last[x];last[x]=len; len++;k2=len;
a[len].x=y;a[len].y=x;a[len].c=;a[len].d=-d;
a[len].next=last[y];last[y]=len; a[k1].other=k2;
a[k2].other=k1;
}
int ans,st,ed;
int list[],d[],pre[],c[];
bool v[];
bool spfa()
{
memset(d,,sizeof(d));d[st]=;
memset(v,false,sizeof(v));v[st]=true;
int head=,tail=;list[]=st;c[st]=inf;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(a[k].c>&&d[y]>d[x]+a[k].d)
{
d[y]=d[x]+a[k].d;
pre[y]=k;
c[y]=min(a[k].c,c[x]);
if(v[y]==false)
{
v[y]=true;
list[tail++]=y;
if(tail==)tail=;
}
}
}
v[x]=false;
head++;if(head==)head=;
}
if(d[ed]==d[])return false;
else
{
ans+=d[ed]*c[ed];
int y=ed;
while(y!=st)
{
int k=pre[y];
a[k].c-=c[ed];
a[a[k].other].c+=c[ed];
y=a[k].x;
}
return true;
}
} int n,mp[][];
int pt(int x,int y){return n*(x-)+y;}
int main()
{
int K;
scanf("%d%d",&n,&K);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&mp[i][j]); for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
if(i!=n)ins(n*n+pt(i,j),pt(i+,j),K,);
if(j!=n)ins(n*n+pt(i,j),pt(i,j+),K,);
ins(pt(i,j),n*n+pt(i,j),,-mp[i][j]);
ins(pt(i,j),n*n+pt(i,j),K-,);
}
st=pt(,);ed=n*n+pt(n,n);
ans=;
while(spfa()==true);
printf("%d\n",-ans);
return ;
}

poj3422

0x6A 网络流初步的更多相关文章

  1. 二分图&网络流初步

    链接 : 最小割&网络流应用 EK太低级了,不用. 那么请看:#6068. 「2017 山东一轮集训 Day4」棋盘,不用EK你试试? dinic模板及部分变形应用见zzz大佬的博客:网络流学 ...

  2. 网络流初步——增广路算法(EK)模板

    #include <iostream> #include <queue> #include<string.h> using namespace std; #defi ...

  3. 网络流初步:<最大流>——核心(增广路算法)(模板)

    增广路的核心就是引入了反向边,使在进行道路探索选择的时候增加了类似于退路的东西[有一点dp的味道??] 具体操作就是:1.首先使用结构体以及数组链表next[ MAXN ]进行边信息的存储 2.[核心 ...

  4. 网络流学习(转载自ssw 的博客)

    众所周知,网络流是探究网络上运输的一种图论分支.但是大多数人在第一次接触这个题时都有些畏惧感(比如说我),大佬可以自信跳过.. 本文包括: 1.网络流的概念及基本性质 2.略谈 Edmonds-Kar ...

  5. 最小割&网络流应用

    重要链接 基础部分链接 : 二分图 & 网络流初步 zzz大佬博客链接 : 网络流学习笔记 重点内容:最小割二元关系新解(lyd's ppt) 题目:网络流相关题目 lyd神犇课件链接 : 网 ...

  6. woj1008feedinganimals2-贪心-网络流

    title: woj1008feedinganimals2-贪心-网络流 date: 2020-03-07 categories: acm tags: [acm,woj,网络流,贪心] 中等题. 标准 ...

  7. ACM暑假集训第三周小结

    这一周学的图论,学了这么些 两种存图的方法:邻接矩阵( map[n][n] ) , 邻接表( headlis[n] , vector<int> G[n] )存图的方法,各有各的好,我的理解 ...

  8. ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  9. Graph Cuts初步理解

    一些知识点的初步理解_8(Graph Cuts,ing...) Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立 ...

随机推荐

  1. 02--Java Socket编程--IO方式

    一.基础知识 1. TCP状态转换知识,可参考: http://www.cnblogs.com/qlee/archive/2011/07/12/2104089.html 2. 数据传输 3. TCP/ ...

  2. 控制台——args参数的赋值方法

    args参数的赋值方法有好几种,主要介绍两种. 外部传参的方法:先找到bin目录下的exe文件,并创建快捷方法,在目标后面追加参数. 控制台主函数入口实现方法 static void Main(str ...

  3. 用Grunt进行CSS文件压缩

    假设你的项目的CSS文件全部放在项目目录下名为css的文件夹中,现在将它压缩合并成一个名为main-min.css的文件,放在css-min文件夹下. (1)首先保证机器安装了node.js. (2) ...

  4. SQL查询性能优化

    使用高效的查询 使用 EXISTS 代替 IN -- 查询A表中同时存在B表的数据 -- 慢 SELECT * FROM Class_A WHERE id IN (SELECT id FROM Cla ...

  5. 用jquery-easyui的布局layout写后台管理页面

    先在官网下载easyui文档 引入头部文件 <link rel="stylesheet" type="text/css" href="${pag ...

  6. 一文读懂架构师都不知道的isinstance检查机制

    起步 通过内建方法 isinstance(object, classinfo) 可以判断一个对象是否是某个类的实例.但你是否想过关于鸭子协议的对象是如何进行判断的呢? 比如 list 类的父类是继 o ...

  7. ajax 禁用按钮防止重复提交

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. 洛谷——P2657 [SCOI2009]windy数

    P2657 [SCOI2009]windy数 题目大意: windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和 ...

  9. char如何储存3个字节或者4个字节

    1.char字符存储的是Unicode编码的代码点,也就是存储的是U+FF00这样的数值,然而我们在调试或者输出到输出流的时候,是JVM或者开发工具按照代码点对应的编码字符输出的. 2. 所以虽然UT ...

  10. 洛谷 P1943 LocalMaxima_NOI导刊2009提高(1)

    我们先考虑第i大数,比它大的数有(n-i)个,显然要使i是Local Maxima,比它大的数必须放在它后面,那么它是Local Maxima的期望是: 那么n个数中Local Maxima个数的期望 ...