poj3204Ikki's Story I

链接

最大流=最小割  这题是求割边集 dinic求出残余网络 两边dfs分别以源点d找到可达点 再以汇点进行d找到可达汇点的点  

如果u,v为割边 那么s->u可达 v->t可达 并且为饱和边

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 #include <algorithm>
  6 using namespace std;
  7 const int INF = 50000;
  8 const int N = 505;
  9 #define M 100005
 10 struct node
 11 {
 12     int u,v,next;
 13     int w;
 14 }edge[M],p[M];
 15 int head[N],t,vis[N],pp[N],dis[N];
 16 int st,en;
 17 bool vis1[N],vis2[N];
 18 void init()
 19 {
 20     t=0;
 21     memset(head,-1,sizeof(head));
 22 }
 23 void add(int u,int v,int w)
 24 {
 25     edge[t].u = u;
 26     edge[t].v = v;
 27     edge[t].w = w;
 28     edge[t].next = head[u];
 29     head[u] = t++;
 30     edge[t].u = v;
 31     edge[t].v = u;
 32     edge[t].w = 0;
 33     edge[t].next = head[v];
 34     head[v] = t++;
 35 }
 36 int bfs()
 37 {
 38     int i,u;
 39     int w;
 40     memset(dis,0,sizeof(dis));
 41     queue<int>q;
 42     q.push(st);
 43     dis[st]=  1;
 44     while(!q.empty())
 45     {
 46         u = q.front();
 47         q.pop();
 48         for(i = head[u] ; i != -1 ; i = edge[i].next)
 49         {
 50             int v = edge[i].v;
 51             w = edge[i].w;
 52             if(!dis[v]&&w>0)
 53             {
 54                 dis[v] = dis[u]+1;
 55                 q.push(v);
 56             }
 57         }
 58     }
 59     if(dis[en]>0) return 1;
 60     return 0;
 61 }
 62 int dfs(int u,int te)
 63 {
 64     int i;
 65     int s;
 66     if(u==en) return te;
 67     int tmp = te;
 68     for(i = head[u] ; i != -1 ; i = edge[i].next)
 69     {
 70         int v = edge[i].v;
 71         int w = edge[i].w;
 72         if(w>0&&dis[v]==dis[u]+1&&(s=dfs(v,min(te,w))))
 73         {
 74             edge[i].w-=s;
 75             edge[i^1].w+=s;
 76             tmp-=s;
 77         }
 78     }
 79     return te-tmp;
 80 }
 81 int dinic()
 82 {
 83     int flow = 0;
 84     while(bfs())
 85     {
 86         flow+=dfs(st,INF);
 87     }
 88     return flow;
 89 }
 90 void dfs1(int u)
 91 {
 92     int i;
 93     for(i = head[u] ; i != -1 ; i= edge[i].next)
 94     if(!vis1[edge[i].v]&&edge[i].w>0)
 95     {
 96         vis1[edge[i].v] = 1;
 97         dfs1(edge[i].v);
 98     }
 99 }
100 void dfs2(int u)
101 {
102     int i;
103     for(i = head[u] ; i != -1 ; i= edge[i].next)
104     {
105         int v =  edge[i].v;
106         //cout<<v<<" "<<edge[i].w<<endl;
107         if(!vis2[edge[i].v]&&edge[i^1].w>0)
108         {
109         vis2[edge[i].v] = 1;
110         dfs2(edge[i].v);
111         }
112     }
113 }
114 int main()
115 {
116     int n,m,i;
117     while(scanf("%d%d",&n,&m)!=EOF)
118     {
119         init();
120         memset(vis1,0,sizeof(vis1));
121         memset(vis2,0,sizeof(vis2));
122         for(i = 1 ;i <= m; i++)
123         {
124             int u,v,c;
125             scanf("%d%d%d",&u,&v,&c);
126             u++,v++;
127             add(u,v,c);
128         }
129         st = 1,en = n;
130         int kk = dinic();
131         //cout<<kk<<endl;
132         vis1[st] = 1;
133         dfs1(st);
134         vis2[en] = 1;
135         dfs2(en);
136         int ans = 0;
137         dinic();
138         for(i = 0; i < t; i+=2)
139         {
140             int u = edge[i].u;
141             int v = edge[i].v;
142             int w = edge[i].w;
143             //cout<<u<<" "<<v<<" "<<vis1[u]<<" "<<vis2[v]<<endl;
144             if(vis1[u]&&vis2[v]&&w<=0)
145             ans++;
146         }
147         cout<<ans<<endl;
148     }
149     return 0;
150 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3712636.html