POJ 3204 最小割

题意:

在一个网络里面,问增大哪条边的容量可以使整个网络的流量增大,输出这种边个数。

题解:

显然这些边是最小割边集的子集。

对于边u-->v,当且仅当能从S沿着非满流的正向边遍历到u,从T沿着非满流的正向边遍历到v时,边u-->v是满足题意的边

两遍dfs求解~

 

View Code
 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdio>

 4 #include <cstdlib>

 5 #include <algorithm>

 6 

 7 #define N 1000

 8 #define M 500010

 9 #define INF 1e9

10 

11 using namespace std;

12 

13 int head[N],next[M],to[M],len[M];

14 int layer[N],q[M*10],vis[N];

15 int n,m,cnt,S,T;

16 

17 inline void add(int u,int v,int w)

18 {

19     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;

20     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;

21 }

22 

23 inline void read()

24 {

25     memset(head,-1,sizeof head); cnt=0;

26     scanf("%d%d",&n,&m);

27     S=1; T=n;

28     for(int i=1,a,b,c;i<=m;i++)

29     {

30         scanf("%d%d%d",&a,&b,&c); a++; b++;

31         add(a,b,c);

32     }

33 }

34 

35 inline bool bfs()

36 {

37     memset(layer,-1,sizeof layer);

38     int h=1,t=2,sta;

39     q[1]=S; layer[S]=0;

40     while(h<t)

41     {

42         sta=q[h++];

43         for(int i=head[sta];~i;i=next[i])

44             if(len[i]&&layer[to[i]]<0)

45             {

46                 layer[to[i]]=layer[sta]+1;

47                 q[t++]=to[i];

48             }

49     }

50     return layer[T]!=-1;

51 }

52 

53 inline int find(int u,int cur_flow)

54 {

55     if(u==T) return cur_flow;

56     int res=0,tmp;

57     for(int i=head[u];~i&&res<cur_flow;i=next[i])

58         if(len[i]&&layer[to[i]]==layer[u]+1)

59         {

60             tmp=find(to[i],min(cur_flow-res,len[i]));

61             len[i]-=tmp; len[i^1]+=tmp; res+=tmp;

62         }

63     if(!res) layer[u]=-1;

64     return res;

65 }

66 

67 inline void dfs1(int u)

68 {

69     vis[u]=1;

70     for(int i=head[u];~i;i=next[i])

71         if(vis[to[i]]==0&&len[i]>0) dfs1(to[i]);

72 }

73 

74 inline void dfs2(int u)

75 {

76     vis[u]=2;

77     for(int i=head[u];~i;i=next[i])

78         if(vis[to[i]]==0&&len[i^1]>0) dfs2(to[i]);

79 }

80 

81 inline void go()

82 {

83     int ans=0;

84     while(bfs()) ans+=find(S,INF);

85     dfs1(S); dfs2(T);

86     ans=0;

87     for(int i=0;i<cnt;i+=2)

88         if(vis[to[i]]==2&&vis[to[i^1]]==1) ans++;

89     printf("%d\n",ans);

90 }

91 

92 int main()

93 {

94     read();

95     go();

96     return 0;

97 }

 

 

你可能感兴趣的:(poj)