P1345 [USACO5.4]奶牛的电信Telecowmunication

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));}

相关文章