ZOJ 2587 最小割

题意:

给出一个带权无向图,给出图中a,b两个点,已知切断一每条边都会产生与这条边权值相同的消耗,切断某些边可以使得a,b之间不连通,在已知一个切边方法消耗最小的方法,判断是否存在与此切割方法消耗相同的方法。

题解:

判断最小割的唯一性!

就是老样子从S沿着非满流的正向边遍历点的总数k1,从T沿着非满流的正向边遍历的点的总数k2,若k1+k2=n(总点数)时最小割唯一。

哎,成了结论了,不会证明。。

后来又想怎么求最小割的总方案数,也不会。。求大神解释!

 

View Code
 1 #include <iostream>

 2 #include <cstdlib>

 3 #include <cstdio>

 4 #include <algorithm>

 5 #include <cstring>

 6 

 7 #define N 1000

 8 #define M 400000

 9 #define INF 1e9

10 

11 using namespace std;

12 

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

14 int q[M*4],layer[N];

15 bool vis[N];

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

17 

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

19 {

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

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

22 }

23 

24 inline void read()

25 {

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

27     memset(vis,0,sizeof vis);

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

29     {

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

31         add(a,b,c); add(b,a,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]=1;

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     for(int i=1;i<=n;i++)

87         if(!vis[i]) {puts("AMBIGUOUS");return;}

88     puts("UNIQUE");

89 }

90 

91 int main()

92 {

93     while(scanf("%d%d%d%d",&n,&m,&S,&T)!=EOF)

94     {

95         if(n==0&&m==0&&S==0&&T==0) break;

96         read(),go();

97     }

98     return 0;

99 } 

 

 

你可能感兴趣的:(ZOJ)