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
原文:https://www.cnblogs.com/Lance1ot/p/9042573.html