zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    两句话的区别在于目录的不同。
    关于系统的操作全在这里了。这个看起来很重要。
    屏幕坐标的方法
    改变轴心的操作。
    关于旋转的变换处理方法。
    对其位置
    点边同事移除的办法处理。
    移动的坐标变换
    判断文件是否存在的函数。
    把节点归零处理
  • 原文地址:https://www.cnblogs.com/yohaha/p/5017489.html
Copyright © 2011-2022 走看看