zoj 2587 Unique Attack (判断最小割是否唯一)

来源:互联网 发布:qq认证群排名优化 编辑:程序博客网 时间:2024/04/28 23:52

题意:

有n台电脑主机被m条网线连着,每两台主机不会被超过一根网线连接。为了破坏两个

超级主机,需要破坏其中的网线使得它们失去联系,已知破坏每条网线所需的费用,求

能得到最小费用的方案是否唯一。


算法:

建图--->无向边。然后求最小割(最大流-最小割定理:最大流的值为最小割的容量)。

然后从st和en分别遍历,由于最大流后,割边一定满流。所以沿着残余网络不为0的边遍历,

分别标记处s集合e集合的点。如果还有点没有标记则最小割不唯一。


#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define maxm 10010#define maxn 810#include<queue>#define INF 0x3f3f3f3fusing namespace std;struct node{    int to,v,next;}e[maxm<<2];int head[maxn],cnt,q[maxn],d[maxn];int vis[maxn],st,en,n,m;void add(int x,int y,int z){    e[cnt].to = y;    e[cnt].v = z;    e[cnt].next = head[x];    head[x] = cnt++;    e[cnt].to = x;    e[cnt].v = 0;    e[cnt].next = head[y];    head[y] = cnt++;}void init(){    memset(head,-1,sizeof(head));    cnt = 0;}bool bfs(){    memset(d,-1,sizeof(d));    int f = 0,r = 0,u;    q[r++] = st;    d[st] = 0;    while(f<r)    {        u = q[f++];        for(int i=head[u];i!=-1;i=e[i].next)        {            int t = e[i].to;            if(e[i].v>0 && d[t]==-1)//>0            {                d[t] = d[u]+1;                q[r++] = t;                if(t==en) return true;            }        }    }    return false;}int dfs(int x,int flow){    if(x==en) return flow;    int ret = 0,dd;    for(int i=head[x];ret<flow && i!=-1;i=e[i].next)    {        int t = e[i].to;        if(d[t] == d[x]+1 && e[i].v)        {            dd = dfs(t,min(flow,e[i].v));            e[i].v-=dd;            e[i^1].v+=dd;            flow-=dd;            ret+=dd;        }    }    if(!ret) d[x]=-1;    return ret;}int Dinic(){    int tmp = 0,maxflow = 0;    while(bfs())    {        while(tmp=dfs(st,INF))            maxflow+=tmp;    }    return maxflow;}void solve(){    memset(vis,0,sizeof(vis));    queue<int> q;    q.push(st);    vis[st] = 1;    while(!q.empty())    {        int f = q.front();        q.pop();        for(int i=head[f];i!=-1;i=e[i].next)        {            int v = e[i].to;            if(e[i].v && !vis[v])            {                vis[v] = 1;                q.push(v);            }        }    }    q.push(en);    vis[en] = -1;    while(!q.empty())    {        int f = q.front();        q.pop();        for(int i = head[f];i!=-1;i=e[i].next)        {            int v = e[i].to;            if(e[i^1].v && !vis[v])            {                vis[v] = -1;                q.push(v);            }        }    }    int flag = 0;    for(int i=1;i<=n;i++)    {       // printf("%d %d\n",i,vis[i]);        if(vis[i]==0)            flag = 1;    }    if(flag)        printf("AMBIGUOUS\n");    else printf("UNIQUE\n");}int main(){    int a,b,c;    while(scanf("%d%d%d%d",&n,&m,&st,&en)!=EOF)    {        if(n==0 && m==0 && st==0 && en==0)            break;        init();        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&a,&b,&c);            add(a,b,c);            add(b,a,c);        }        Dinic();        solve();    }    return 0;}




0 0