zoukankan      html  css  js  c++  java
  • POJ1149 最大流经典建图PIG

    题意:
          有一个人,他有m个猪圈,每个猪圈里都有一定数量的猪,但是他没有钥匙,然后依次来了n个顾客,每个顾客都有一些钥匙,还有他要卖猪的数量,每个顾客来的时候主人用顾客的钥匙打开相应的门,可以调整猪的数量,然后卖给一些猪给这个顾客(卖多少自己决定),顾客走之后所有的们就都锁上了,问主人最多能买多少头猪。


    思路:
          经典的建图,这已经是我第三次做这个题目了,大一,大二,大三每年做流的时候都会想到它,然后回来做一次,没办法,感觉比较经典,虽然现在做着直接1A没有第一次做的时候千辛万苦ac那么成就感了,但是经典就是经典,大体说下思路吧,这个题解写了好多次了,题目中说来了一个顾客之后可以调整数量,那么我们直接就把这个顾客所有能打开的猪圈变成一个猪圈,用虚拟出来的一个点代替,以后无论谁在来,只要访问这其中的某个猪圈就用他当前虚拟的点来代表他,可以开一个数组映射每个猪圈当前虚拟的点,虚拟的点可以再被虚拟,就像OS一样,可以一层一层的虚拟,我的建图是这样(可以倒过来,或者是用别的姿势,怎么都行,写着顺手,思路清晰就行):


    (1) s 向所有的顾客连接一条边 流量是顾客要买的猪的数量
    (2) 所有的猪圈向t连接一条边,流量是猪圈的猪的数量
    (3) 对于每一个顾客,我们首先虚拟出来一个点,然后把这个顾客所有连接的点都指向这个    虚拟的点,比如当前的这个顾客有三把钥匙1,2,3,因为这三个猪圈可以直接调整数量    了,所以我们可以让虚拟出来的这个点a代替当前这步的三个点,1->a ,2->a ,3->a,然    后在更新上面说的那个hash[],hash[1] = a ,hash[2] = a ,hash[3] = a,以后只要是    访问1,2,3中的任何一个,直接访问a,就行了,然后在建立一条当前顾客到新虚拟出来     的这个点的边,流量INF。
    ok,就是以上那些,要是不明白可以自己按照上面的见图思路画个图,很容易理解。








    #include<queue>
    #include<stdio.h>
    #include<string.h>


    #define N_node 1500
    #define N_edge 100000
    #define INF 1000000000


    using namespace std;


    typedef struct
    {
        int to ,cost ,next;
    }STAR;


    typedef struct
    {
        int x ,t;
    }DEP;


    STAR E[N_edge];
    DEP xin ,tou;
    int list[N_node] ,listt[N_node] ,tot;
    int deep[N_node] ,hash[N_node];


    void add(int a ,int b ,int c)
    {
        E[++tot].to = b;
        E[tot].cost = c;
        E[tot].next = list[a];
        list[a] = tot;


        E[++tot].to = a;
        E[tot].cost = 0;
        E[tot].next = list[b];
        list[b] = tot;


    }


    bool BFS_DEEP(int s ,int t ,int n)
    {
        memset(deep ,255 ,sizeof(deep));
        xin.x = s ,xin.t = 0;
        queue<DEP>q;
        q.push(xin);
        deep[s] = 0;
        while(!q.empty())
        {
            tou = q.front();
            q.pop();
            for(int k = list[tou.x] ;k ;k = E[k].next)
            {
                xin.x = E[k].to;
                xin.t = tou.t + 1;
                if(deep[xin.x] != -1 || !E[k].cost)
                continue;
                deep[xin.x] = xin.t;
                q.push(xin);
            }
        }
        for(int i = 0 ;i <= n ;i ++)
        listt[i] = list[i];
        return deep[t] != -1;
    }


    int minn(int x ,int y)
    {
        return x < y ? x : y;
    }


    int DFS_Flow(int s ,int t ,int flow)
    {
        if(s == t) return flow;
        int nowflow = 0;
        for(int k = listt[s] ;k ;k = E[k].next)
        {
            listt[s] = k;
            int c = E[k].cost;
            int to = E[k].to;
            if(!c || deep[to] != deep[s] + 1)
            continue;
            int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));
            nowflow += tmp;
            E[k].cost -= tmp;
            E[k^1].cost += tmp;
            if(nowflow == flow) break;
        }
        if(!nowflow) deep[s] = 0;
        return nowflow;
    }


    int DINIC(int s ,int t ,int n)
    {
        int ans = 0;
        while(BFS_DEEP(s ,t ,n))
        {
            ans += DFS_Flow(s ,t ,INF);
        }
        return ans;
    }


    int main ()
    {
        int n ,m ,i ,q ,a;
        while(~scanf("%d %d" ,&m ,&n))
        {
            memset(list ,0 ,sizeof(list));
            tot = 1;
            for(i = 1 ;i <= m ;i ++)
            {
                scanf("%d" ,&a);
                add(i + n ,m + n + n + 1 ,a);
                hash[i] = i + n;
            }


            for(i = 1 ;i <= n ;i ++)
            {
                scanf("%d" ,&q);
                while(q--)
                {
                    scanf("%d" ,&a);
                    add(i + n + m ,hash[a] ,INF);
                    hash[a] = i + n + m;
                }
                add(i ,i + n + m ,INF);
                scanf("%d" ,&a);
                add(0 ,i ,a);
            }
            printf("%d " ,DINIC(0 ,n + m + n + 1 ,n + m + n + 1));
        }
        return 0;
    }
















  • 相关阅读:
    使用phpstorm和xdebug实现远程调试
    让VS2010/VS2012添加新类时自动添加public关键字
    C#壓縮文件幫助類 使用ICSharpCode.SharpZipLib.dll
    C#使用ICSharpCode.SharpZipLib.dll压缩文件夹和文件
    用C#制作PDF文件全攻略
    多条件动态LINQ 组合查询
    bootstrap fileinput 文件上传工具
    Web Uploader文件上传插件
    Bootstrap文件上传插件File Input的使用
    flashfxp v3.7 注册码
  • 原文地址:https://www.cnblogs.com/csnd/p/12062531.html
Copyright © 2011-2022 走看看