ZOJ 2587 最小割
题意:
给出一个带权无向图,给出图中a,b两个点,已知切断一每条边都会产生与这条边权值相同的消耗,切断某些边可以使得a,b之间不连通,在已知一个切边方法消耗最小的方法,判断是否存在与此切割方法消耗相同的方法。
题解:
判断最小割的唯一性!
就是老样子从S沿着非满流的正向边遍历点的总数k1,从T沿着非满流的正向边遍历的点的总数k2,若k1+k2=n(总点数)时最小割唯一。
哎,成了结论了,不会证明。。
后来又想怎么求最小割的总方案数,也不会。。求大神解释!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
没有人能阻止我前进的步伐,除了我自己!