判断最小割是否唯一,网上得到的算法。从S和T出发,分别沿着残余网络访问结点,若最后所有结点都被访问到,那么唯一,否则不唯一
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std; const int inf=1<<29; const int maxn=1e3+10; const int maxm=5e4+10; int e,head[maxn],pnt[maxm],flow[maxm],nxt[maxm],level[maxm]; int n,m,st,des; bool vis[maxn]; queue<int> q; void AddEdge(int u,int v,int f) { pnt[e]=v;nxt[e]=head[u];flow[e]=f;head[u]=e++; pnt[e]=u;nxt[e]=head[v];flow[e]=0;head[v]=e++; } bool BFS() { memset(level,0,sizeof(level)); level[st]=1; q.push(st); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=nxt[i]) if(flow[i]&&!level[pnt[i]]) { level[pnt[i]]=level[u]+1; q.push(pnt[i]); } } return level[des]; } int DFS(int u,int maxf) { if(u==des||!maxf) return maxf; int f=0; for(int i=head[u];i!=-1;i=nxt[i]) if(flow[i]&&level[pnt[i]]==level[u]+1) { int t=DFS(pnt[i],min(flow[i],maxf-f)); if(t>0) { flow[i]-=t; flow[i^1]+=t; f+=t; if(f==maxf) break; } else level[pnt[i]]=0; } return f; } int maxflow() { int ans=0; while(BFS()) ans+=DFS(st,inf); return ans; } void dfs1(int u,int f) { vis[u]=1; for(int i=head[u];i!=-1;i=nxt[i]) { if(vis[pnt[i]]||pnt[i]==f||!flow[i]) continue; dfs1(pnt[i],-1); } } void dfs2(int u,int f) { vis[u]=1; for(int i=head[u];i!=-1;i=nxt[i]) { if(vis[pnt[i]]||pnt[i]==f||!flow[i^1]) continue; dfs2(pnt[i],-1); } } void solve() { int f=maxflow(); memset(vis,0,sizeof(vis)); dfs1(st,-1); dfs2(des,-1); int cnt=0; for(int i=1;i<=n;i++) if(vis[i]) cnt++; if(cnt==n) printf("UNIQUE\n"); else printf("AMBIGUOUS\n"); } int main() { while(scanf("%d%d%d%d",&n,&m,&st,&des)&&(n+m+st+des)) { e=0; memset(head,-1,sizeof(head)); for(int i=0;i<m;i++) { int u,v,f; scanf("%d%d%d",&u,&v,&f); AddEdge(u,v,f); AddEdge(v,u,f); } solve(); } return 0; }