ZOJ-2587-Unique Attack

来源:互联网 发布:真实的朝鲜 知乎 编辑:程序博客网 时间:2024/05/21 14:00

判断最小割是否唯一,网上得到的算法。从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;}


0 0