zoj 2587 Unique Attack (判断最小割是否唯一)
2014-08-12 09:13
363 查看
题意:
有n台电脑主机被m条网线连着,每两台主机不会被超过一根网线连接。为了破坏两个
超级主机,需要破坏其中的网线使得它们失去联系,已知破坏每条网线所需的费用,求
能得到最小费用的方案是否唯一。
算法:
建图--->无向边。然后求最小割(最大流-最小割定理:最大流的值为最小割的容量)。
然后从st和en分别遍历,由于最大流后,割边一定满流。所以沿着残余网络不为0的边遍历,
分别标记处s集合e集合的点。如果还有点没有标记则最小割不唯一。
有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 0x3f3f3f3f using 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; }
相关文章推荐
- ZOJ 2587--Unique Attack【判断最小割是否唯一】
- ZOJ 2587 && ACdream1235 Unique Attack(判断最小割是否唯一)
- ZOJ 2587 Unique Attack 判断最小割是否唯一
- zoj 2587 Unique Attack 判断最小割是否唯一 sap+dfs
- zoj 2587 Unique Attack 【判断最小割是否唯一】
- ZOJ 2587 - Unique Attack 最小割,判断割边集是否唯一
- ZOJ 2587 Unique Attack 判断最小割是否唯一
- ZOJ-2587 Unique Attack(最小割是否唯一判定)
- Unique Attack (zoj 2587 判定最小割是否唯一)
- zju 2587 判断最小割是否唯一
- ZOJ 2587 Unique Attack 判最小割唯一
- ZOJ 2587 Unique Attack 判最小割唯一
- zoj 2587(最小割是否唯一)
- zoj 2587 Unique Attack(判断最小割的唯一性)
- ZOJ 2587 Unique Attack(最小割唯一性判断)
- zju 2587 判断最小割是否唯一
- zoj 2587 (最小割是否唯一+dinic非递归模版)
- POJ 1679 The Unique MST (prim判断最小生成树是否唯一)
- poj1679(次小生成树判断最小生成树是否唯一)
- poj 1679 The Unique MST 判断最小生成树是否唯一(图论)