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 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289

posted on 2015-04-25 11:13  xiao_xin  阅读(86)  评论(0编辑  收藏  举报

导航