zoukankan      html  css  js  c++  java
  • ZOJ 2587 Unique Attack 判断最小割是否唯一

    很裸的判断最小割是否唯一。判断方法是先做一遍最大流求最小割,然后从源点和汇点分别遍历所有能够到达的点,看是否覆盖了所有的点,如果覆盖了所有的点,那就是唯一的,否则就是不唯一的。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <string>
    #include <iostream>
    #include <map>
    #include <cstdlib>
    #include <list>
    #include <set>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 800 + 5;
    const int maxm = 80000;
    const int INF = INT_MAX / 2;
    int n,m,s,t;
    int first[maxn],nxt[maxm];
    int ecnt,v[maxm],cap[maxm];
    int q[maxn],qs,qe;
    bool vis[maxn];
    
    void adde(int uu,int vv,int ww) {
        v[ecnt] = vv; cap[ecnt] = ww; nxt[ecnt] = first[uu]; first[uu] = ecnt++;
        v[ecnt] = uu; cap[ecnt] = 0; nxt[ecnt] = first[vv]; first[vv] = ecnt++;
    }
    
    int level[maxn];
    bool bfs() {
        memset(level,0,sizeof(level));
        qs = qe = 0;
        q[qe++] = s;
        level[s] = 1;
        while(qs < qe) {
            int now = q[qs++];
            if(now == t) break;
            for(int i = first[now];~i;i = nxt[i]) {
                if(cap[i] && level[v[i]] == 0) {
                    q[qe++] = v[i]; level[v[i]] = level[now] + 1;
                }
            }
        }
        return level[t];
    }
    
    int dfs(int now,int alpha) {
        if(now == t) return alpha;
        int sum = 0;
        for(int i = first[now];~i && alpha;i = nxt[i]) {
            if(cap[i] && level[v[i]] == level[now] + 1) {
                int ret = dfs(v[i],min(alpha,cap[i]));
                sum += ret; alpha -= ret;
                cap[i] -= ret; cap[i ^ 1] += ret;
            }
        }
        if(sum == 0) level[now] = -1;
        return sum;
    }
    
    void solve() {
        //先做一遍最大流   
        while(bfs()) dfs(s,INF);
        //分别从起点和终点做一遍bfs
        memset(vis,0,sizeof(vis));
        qs = qe = 0;
        q[qe++] = s;
        vis[s] = true;
        while(qs < qe) {
            int now = q[qs++];
            for(int i = first[now];~i;i = nxt[i]) {
                if(cap[i] && !vis[v[i]]) {
                    vis[v[i]] = true; q[qe++] = v[i];
                }
            }
        }
        qs = qe = 0;
        q[qe++] = t;
        vis[t] = true;
        while(qs < qe) {
            int now = q[qs++];
            for(int i = first[now];~i;i = nxt[i]) {
                if(cap[i ^ 1] && !vis[v[i]]) {
                    vis[v[i]] = true; q[qe++] = v[i];
                }
            }
        }
        for(int i = 1;i <= n;i++) {
            if(!vis[i]) {
                puts("AMBIGUOUS");
                return;
            }
        }
        puts("UNIQUE");
    }
    
    int main() {
        while(scanf("%d%d%d%d",&n,&m,&s,&t),n) {
            memset(first,-1,sizeof(first));
            ecnt = 0;
            for(int i = 0;i < m;i++) {
                int a,b,c; scanf("%d%d%d",&a,&b,&c);
                adde(a,b,c); adde(b,a,c);
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    kfx格式的复活
    HTC(HTML Component)开发简介
    window.open window.showModelDialog 打开一个新窗口/子窗口中调用父窗口的方法
    用 Firebug 动态调试和优化应用程序
    HTC——浏览器上的舞者
    innerHTML、innerText和outerHTML、outerText的区别
    window.parent与window.opener的区别与使用
    window.parent与window.opener、window.showModalDialog的区别 opener和showModalDialog刷新父页面的方法
    HTML Component(HTC)
    Hibernate下数据批量处理解决方案
  • 原文地址:https://www.cnblogs.com/rolight/p/3873313.html
Copyright © 2011-2022 走看看