zoukankan      html  css  js  c++  java
  • POJ 1815 Friendship ★(字典序最小点割集)

    题意】给出一个无向图,和图中的两个点s,t。求至少去掉几个点后才能使得s和t不连通,输出这样的点集并使其字典序最大。 不错的题,有助于更好的理解最小割和求解最小割的方法~ 【思路】 问题模型很简单,就是无向图的点连通度,也就是最小点割集。麻烦之处在于需要使得点割集方案的字典序最大。这样的话通常的dfs划分点集的方法就行不通了。我们采取贪心的策略:枚举1~N的点,在残留网络中dfs检查其代表的边的两端点是否连通,如果不连通则该点可以为点割,那么我们就让他是点割,加入到答案中,然后删掉这条边更新最大流。重复这个过程直到扫描完所有点。 PS:很多人判断点是否可以是点割时是先删掉边然后判断流是否减小,我觉得这样是不是麻烦了?因为如果不减小的话(不是点割)还得把他还原,相当于重新构了两次图。  
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define MID(x,y) ((x+y)/2)
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    const int MAXV = 505;
    const int MAXE = 50005;
    const int oo = 0x3fffffff;
    
    /* Dinic-2.0-2013.07.21: adds template.  double & int 转换方便多了,也不易出错 ~*/
    template 
    struct Dinic{
        struct node{
            int u, v;
            T flow;
            int opp;
            int next;
        }arc[2*MAXE];
        int vn, en, head[MAXV];
        int cur[MAXV];
        int q[MAXV];
        int path[2*MAXE], top;
        int dep[MAXV];
        void init(int n){
            vn = n;
            en = 0;
            mem(head, -1);
        }
        void insert_flow(int u, int v, T flow){
            arc[en].u = u;
            arc[en].v = v;
            arc[en].flow = flow;
            arc[en].next = head[u];
            head[u] = en ++;
    
            arc[en].u = v;
            arc[en].v = u;
            arc[en].flow = 0;
            arc[en].next = head[v];
            head[v] = en ++;
        }
        bool bfs(int s, int t){
            mem(dep, -1);
            int lq = 0, rq = 1;
            dep[s] = 0;
            q[lq] = s;
            while(lq < rq){
                int u = q[lq ++];
                if (u == t){
                    return true;
                }
                for (int i = head[u]; i != -1; i = arc[i].next){
                    int v = arc[i].v;
                    if (dep[v] == -1 && arc[i].flow > 0){
                        dep[v] = dep[u] + 1;
                        q[rq ++] = v;
                    }
                }
            }
            return false;
        }
        T solve(int s, int t){
            T maxflow = 0;
            while(bfs(s, t)){
                int i, j;
                for (i = 1; i <= vn; i ++)  cur[i] = head[i];
                for (i = s, top = 0;;){
                    if (i == t){
                        int mink;
                        T minflow = 0x3fffffff;
                        for (int k = 0; k < top; k ++)
                            if (minflow > arc[path[k]].flow){
                                minflow = arc[path[k]].flow;
                                mink = k;
                            }
                        for (int k = 0; k < top; k ++)
                            arc[path[k]].flow -= minflow, arc[path[k]^1].flow += minflow;
                        maxflow += minflow;
                        top = mink;
                        i = arc[path[top]].u;
                    }
                    for (j = cur[i]; j != -1; cur[i] = j = arc[j].next){
                        int v = arc[j].v;
                        if (arc[j].flow && dep[v] == dep[i] + 1)
                            break;
                    }
                    if (j != -1){
                        path[top ++] = j;
                        i = arc[j].v;
                    }
                    else{
                        if (top == 0)   break;
                        dep[i] = -1;
                        i = arc[path[-- top]].u;
                    }
                }
            }
            return maxflow;
        }
    };
    Dinic  dinic;
    
    bool map[MAXV][MAXV];
    int n, s, t;
    bool vis[MAXV];
    bool dfs(int u, int t){
        vis[u] = 1;
        if (u == t)
            return true;
        for (int i = dinic.head[u]; i != -1; i = dinic.arc[i].next){
            if (dinic.arc[i].flow <= 0) continue;
            int v = dinic.arc[i].v;
            if (!vis[v]){
                if (dfs(v, t)){
                    return true;
                }
            }
        }
        return false;
    }
    bool del[MAXV];
    void update_flow(){
        dinic.init(2*n);
        for (int i = 1; i <= n; i ++){
            if (del[i]) continue;
            if (i != s && i != t)
                dinic.insert_flow(i, n+i, 1);
            else{
                dinic.insert_flow(i, n+i, oo);
            }
            for (int j = 1; j <= n; j ++){
                if (del[j]) continue;
                if (i != j && map[i][j] == 1){
                    dinic.insert_flow(n+i, j, oo);
                }
            }
        }
        dinic.solve(s, t);
    }
    int main(){
    	//freopen("test.in", "r", stdin);
    	//freopen("test.out", "w", stdout);
        while(scanf("%d %d %d", &n, &s, &t) != EOF){
            dinic.init(2*n);
            bool if_answer = 1;
            for (int i = 1; i <= n; i ++){
                if (i != s && i != t)
                    dinic.insert_flow(i, n+i, 1);
                else{
                    dinic.insert_flow(i, n+i, oo);
                }
                for (int j = 1; j <= n; j ++){
                    scanf("%d", &map[i][j]);
                    if (i != j && map[i][j] == 1){
                        dinic.insert_flow(n+i, j, oo);
                    }
                    if ((i == s && j == t && map[i][j] == 1))
                        if_answer = 0;
                }
            }
            if (!if_answer){
                puts("NO ANSWER!");
                continue;
            }
            int res = dinic.solve(s, t);
            printf("%d
    ", res);
            vector  mincut;
            mem(del, false);
            if (res){
                for (int i = 1; i <= n; i ++){
                    mem(vis, 0);
                    if (!dfs(i, n+i)){
                        mincut.push_back(i);
                        del[i] = true;
                        update_flow();
                    }
                }
                for (int i = 0; i < (int)mincut.size(); i ++){
                    if (i == 0)
                        printf("%d", mincut[i]);
                    else
                        printf(" %d", mincut[i]);
                }
                puts("");
            }
        }
    	return 0;
    }
    
  • 相关阅读:
    父子进程 signal 出现 Interrupted system call 问题
    一个测试文章
    《淘宝客户端 for Android》项目实战 html webkit android css3
    Django 中的 ForeignKey ContentType GenericForeignKey 对应的数据库结构
    coreseek 出现段错误和Unigram dictionary load Error 新情况(Gentoo)
    一个 PAM dbus 例子
    漫画统计学 T分数
    解决 paramiko 安装问题 Unable to find vcvarsall.bat
    20141202
    js
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114270.html
Copyright © 2011-2022 走看看