hdu4289 最大流:拆点/最小割
把以前没做的网络流模型现在都补一下==
本题是比较经典的只有点权,题目问在哪些点放置东西使不流通代价最小,拆点然后就是最小割,跑一遍最大流即可
对于点i,i->i+n x
对于双向边 x+n->y inf
y+n->x inf
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #include<vector> 5 #include<algorithm> 6 #define maxn 405 7 #define maxm 100005 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 struct Edge{ 11 int from,to,cap,flow; 12 }; 13 struct dinic{ 14 int s,t,n; 15 vector<Edge>edges; 16 vector<int>G[maxn]; 17 bool vis[maxn]; 18 int cur[maxn],d[maxn]; 19 void init(int _s,int _t,int _n){ 20 s=_s; t=_t; n=_n; 21 edges.clear(); 22 for (int i=0;i<=_n;i++) G[i].clear(); 23 } 24 void add(int from,int to,int cap){ 25 Edge e; 26 e.from=from; e.to=to; e.cap=cap; e.flow=0; 27 edges.push_back(e); 28 e.from=to; e.to=from; e.cap=0; e.flow=0; 29 edges.push_back(e); 30 int m=edges.size(); 31 G[from].push_back(m-2); G[to].push_back(m-1); 32 } 33 bool bfs(){ 34 memset(vis,0,sizeof(vis)); 35 queue<int>q; 36 q.push(s); d[s]=0; vis[s]=1; 37 while (!q.empty()){ 38 int x=q.front(); q.pop(); 39 for (int i=0;i<G[x].size();i++){ 40 Edge& e=edges[G[x][i]]; 41 if (!vis[e.to]&&e.cap>e.flow){ 42 vis[e.to]=1; 43 d[e.to]=d[x]+1; 44 q.push(e.to); 45 } 46 } 47 } 48 return vis[t]; 49 } 50 int dfs(int x,int a){ 51 if (x==t||a==0) return a; 52 int flow=0,f; 53 for (int& i=cur[x];i<G[x].size();i++){ 54 Edge& e=edges[G[x][i]]; 55 if (d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){ 56 e.flow+=f; 57 edges[G[x][i]^1].flow-=f; 58 flow+=f; 59 a-=f; 60 if (a==0) break; 61 } 62 } 63 return flow; 64 } 65 int maxflow(){ 66 int flow=0; 67 while (bfs()){ 68 memset(cur,0,sizeof(cur)); 69 flow+=dfs(s,inf); 70 } 71 return flow; 72 } 73 }g; 74 int main() 75 { 76 int n,m,i,s,e,x,y; 77 while (~scanf("%d%d",&n,&m)){ 78 scanf("%d%d",&s,&e); 79 g.init(0,2*n+1,2*n+2); 80 g.add(0,s,inf); g.add(e+n,2*n+1,inf); 81 for (i=1;i<=n;i++){ 82 scanf("%d",&x); 83 g.add(i,i+n,x); 84 } 85 for (i=1;i<=m;i++){ 86 scanf("%d%d",&x,&y); 87 g.add(x+n,y,inf); 88 g.add(y+n,x,inf); 89 } 90 printf("%d\n",g.maxflow()); 91 } 92 return 0; 93 }