zoj 2587 Unique Attack 最小割判定

题目链接

让你判断最小割是否唯一。

判断方法是, 先求一遍最大流, 然后从源点dfs一次, 搜索未饱和边的数目。 从汇点dfs一次, 同样也是搜索未饱和边的数目, 看总和是否等于n。 如果等于n那么唯一。

具体可以看这里, http://www.cnblogs.com/Lyush/archive/2013/05/01/3053640.html

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define mem(a) memset(a, 0, sizeof(a))
  4 #define mem1(a) memset(a, -1, sizeof(a))
  5 const int inf = 1e8;
  6 const int maxn = 2e4+5;
  7 int head[maxn*2], s, t, num, q[maxn*3], dis[1005], vis[1005], cnt;
  8 struct node
  9 {
 10     int to, nextt, c;
 11 }e[maxn*2];
 12 void init() {
 13     mem1(head);
 14     num = cnt = 0;
 15     mem(vis);
 16 }
 17 void add(int u, int v, int c) {
 18     e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++;
 19     e[num].to = u; e[num].nextt = head[v]; e[num].c = c; head[v] = num++;
 20 }
 21 int bfs() {
 22     int u, v, st = 0, ed = 0;
 23     mem(dis);
 24     dis[s] = 1;
 25     q[ed++] = s;
 26     while(st<ed) {
 27         u = q[st++];
 28         for(int i = head[u]; ~i; i = e[i].nextt) {
 29             v = e[i].to;
 30             if(e[i].c&&!dis[v]) {
 31                 dis[v] = dis[u]+1;
 32                 if(v == t)
 33                     return 1;
 34                 q[ed++] = v;
 35             }
 36         }
 37     }
 38     return 0;
 39 }
 40 int dfs(int u, int limit) {
 41     if(u == t)
 42         return limit;
 43     int cost = 0;
 44     for(int i = head[u]; ~i; i = e[i].nextt) {
 45         int v = e[i].to;
 46         if(e[i].c&&dis[u] == dis[v]-1) {
 47             int tmp = dfs(v, min(limit-cost, e[i].c));
 48             if(tmp>0) {
 49                 e[i].c -= tmp;
 50                 e[i^1].c += tmp;
 51                 cost += tmp;
 52                 if(cost == limit)
 53                     break;
 54             } else {
 55                 dis[v] = -1;
 56             }
 57         }
 58     }
 59     return cost;
 60 }
 61 int dinic() {
 62     int ans = 0;
 63     while(bfs()) {
 64         ans += dfs(s, inf);
 65     }
 66     return ans;
 67 }
 68 void dfs(int u) {
 69     vis[u] = 1;
 70     cnt++;
 71     for(int i = head[u]; ~i; i = e[i].nextt) {
 72         int v = e[i].to;
 73         if(!vis[v]&&e[i].c) {
 74             dfs(v);
 75         }
 76     }
 77 }
 78 void dfs1(int u) {
 79     vis[u] = 1;
 80     cnt++;
 81     for(int i = head[u]; ~i; i = e[i].nextt) {
 82         int v = e[i].to;
 83         if(!vis[v]&&e[i^1].c) {
 84             dfs1(v);
 85         }
 86     }
 87 }
 88 int main()
 89 {
 90     int n, m, x, y, z;
 91     while(scanf("%d%d%d%d", &n, &m, &s, &t)) {
 92         if(n+m+s+t==0)
 93             break;
 94         init();
 95         while(m--) {
 96             scanf("%d%d%d", &x, &y, &z);
 97             add(x, y, z);
 98         }
 99         int ans = dinic();
100         dfs(s);
101         dfs1(t);
102         if(cnt == n) {
103             cout<<"UNIQUE"<<endl;
104         } else {
105             cout<<"AMBIGUOUS"<<endl;
106         }
107     }
108 }

 

posted on 2015-12-03 20:16  yohaha  阅读(163)  评论(0编辑  收藏  举报

导航