標籤:dfs eof lin return push string int memset struct
P1345 [USACO5.4]奶牛的電信Telecowmunication
實際上是求點割。
我們可以將一個點拆成兩個點,其中只有一條、容量為1的邊。
然後求最小割。最小割等於最大流233
dinci就ok了
#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<queue>using namespace std;struct node{ int point; int nxt; int weight;};node line[6000];int head[6000],tail=-1;void add(int x,int y,int z){ line[++tail].point=y; line[tail].weight=z; line[tail].nxt=head[x]; head[x]=tail; line[++tail].point=x; line[tail].weight=0; line[tail].nxt=head[y]; head[y]=tail;}int dep[6000];int cur[6000];int n,m,s,t;bool BFS(int begin,int end){ memset(dep,0,sizeof(dep)); queue<int>q; dep[begin]=1; q.push(begin); for(int i=1;i<=2*n;i++) cur[i]=head[i]; while(!q.empty()) { int pas=q.front(); q.pop(); for(int i=head[pas];i!=-1;i=line[i].nxt) if(line[i].weight&&!dep[line[i].point]) { dep[line[i].point]=dep[pas]+1; q.push(line[i].point); } } if(dep[end]) return true; return false;}int DFS(int now,int aim,int limte){ if(now==aim||!limte) return limte; int flow=0,f; for(int i=cur[now];i!=-1;i=line[i].nxt) { cur[now]=i; if(dep[line[i].point]==dep[now]+1&&(f=DFS(line[i].point,aim,min(limte,line[i].weight)))) { limte-=f; flow+=f; line[i].weight-=f; line[i^1].weight+=f; if(!limte) break; } } return flow;}int dinic(int begin,int end){ int res=0; while(BFS(begin,end)) res+=DFS(begin,end,0x7fffffff); return res;}int main(){ scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=2*n;i++) head[i]=-1; for(int i=1;i<=n;i++) add(i,i+n,1); int a,b; for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); add(a+n,b,0x7fffffff); add(b+n,a,0x7fffffff); } printf("%d",dinic(s+n,t));}
P1345 [USACO5.4]奶牛的電信Telecowmunication