標籤:bool cst down return scanf queue log 奶牛 end
對於每個點,把它拆成有權值為1的邊相連的兩個點,原邊是inf。
邊的起點統一加n,ss也加n
這就成了最小割
#include <iostream>#include <cstring>#include <cstdio>#include <queue>using namespace std;int n, m, ss, tt, hea[205], cnt, uu, vv, maxFlow=0, lev[205];const int oo=0x3f3f3f3f;queue<int> d;struct Edge{ int too, nxt, val;}edge[4005];void add_edge(int fro, int too, int val){ edge[cnt].nxt = hea[fro]; edge[cnt].too = too; edge[cnt].val = val; hea[fro] = cnt++;}void addEdge(int fro, int too, int val){ add_edge(fro, too, val); add_edge(too, fro, 0);}bool bfs(){ memset(lev, 0, sizeof(lev)); d.push(ss); lev[ss] = 1; while(!d.empty()){ int x=d.front(); d.pop(); for(int i=hea[x]; i!=-1; i=edge[i].nxt){ int t=edge[i].too; if(!lev[t] && edge[i].val>0){ lev[t] = lev[x] + 1; d.push(t); } } } return lev[tt]!=0;}int dfs(int x, int lim){ if(x==tt) return lim; int addFlow=0; for(int i=hea[x]; i!=-1 && addFlow<lim; i=edge[i].nxt){ int t=edge[i].too; if(lev[t]==lev[x]+1 && edge[i].val>0){ int tmp=dfs(t, min(lim-addFlow, edge[i].val)); edge[i].val -= tmp; edge[i^1].val += tmp; addFlow += tmp; } } return addFlow;}void dinic(){ while(bfs()) maxFlow += dfs(ss, oo);}int main(){ memset(hea, -1, sizeof(hea)); cin>>n>>m>>ss>>tt; ss += n; for(int i=1; i<=n; i++) addEdge(i, i+n, 1); for(int i=1; i<=m; i++){ scanf("%d %d", &uu, &vv); addEdge(uu+n, vv, oo); addEdge(vv+n, uu, oo); } dinic(); cout<<maxFlow<<endl; return 0;}
luogu1345 [USACO5.4]奶牛的電信Telecowmunication