zoukankan      html  css  js  c++  java
  • POJ 1149 网络流 合并建图

    这个题目我敲了一个简单的EK,这不是难点

    难点在于建图,按题目的要求 每个猪圈和顾客都建点的话,那也太多了。。。我看了Edelweiss里面的缩点方法才建好的图,哎,惭愧啊

    实际那些猪圈根本不需要单独建点,猪圈无非就是向顾客输送流量 以及向同时开着的猪圈输送流量,这一步可以直接缩为,当某个猪圈被第一次打开,它里面的流量就全部输送给那个顾客那个点,而且可以叠加,因为每一次猪圈是可以互通的,而且猪圈本身是没有容量限制,如果有限制,那就还得再考虑。

    此外,每次对猪圈的接下来的访问者都进行建边。用来输送之后的流量

    处理好初始点和结束点。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define INF 1<<30
    using namespace std;
    int m,n;
    int pigs[1010],cap[110][110],f[110][110],vis[1010][110],buys;
    int inq[1010],cnt[1010];
    void init(){
        memset(cap,0,sizeof cap);
        memset(f,0,sizeof cap);
        memset(vis,0,sizeof vis);
        memset(inq,0,sizeof inq);
        memset(cnt,0,sizeof cnt);
    }
    int ans,q[110],a[110],p[110];
    void ek()
    {
        ans=0;
        const int M=105;
        for (;;){
            memset(a,0,sizeof a);
            int head,rear;
            head=rear=0;
            a[0]=INF;
            q[rear++]=0;
            while(head!=rear){
                int u=q[head++];
                if (head>=M) head%=M;
                for (int v=0;v<=n+1;v++) if (!a[v] && cap[u][v]>f[u][v]){
                    p[v]=u;
                    q[rear++]=v;
                    if (rear>=M) rear%=M;
                    a[v]=min(a[u],cap[u][v]-f[u][v]);
                }
            }
            if (a[n+1]==0) break;
            for (int u=n+1;u!=0;u=p[u]){
                f[p[u]][u]+=a[n+1];
                f[u][p[u]]-=a[n+1];
            }
            ans+=a[n+1];
        }
    }
    
    int main()
    {
        while (scanf("%d%d",&m,&n)!=EOF)
        {
            init();
            int tmp,a;
            for (int i=1;i<=m;i++) scanf("%d",&pigs[i]);
            for (int i=1;i<=n;i++){
                scanf("%d",&tmp);
                for (int j=0;j<tmp;j++){
                    scanf("%d",&a);
                    vis[a][cnt[a]++]=i;
                    if (inq[a]) continue;
                    inq[a]=1;
                    cap[0][i]+=pigs[a];
                }
                scanf("%d",&buys);
                cap[i][n+1]=buys;
            }
            for (int i=1;i<=m;i++){
                for (int j=0;j<cnt[i]-1;j++){
                        int a=vis[i][j];
                        int b=vis[i][j+1];
                        cap[a][b]=INF;
                    }
            }
       }
            ek();
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    第十三篇:一点一滴学ibatis(二)映射文件
    第十二篇:随手记一下javaBean的setter,getter方法的命名问题
    第十一篇:一点一滴学ibatis(一)
    第十篇:javaScript中的JSON总结
    第九篇:Spring的applicationContext.xml配置总结
    第八篇:ZTree操作总结
    第六篇:fastJson常用方法总结
    第五篇:zTree节点的一些操作,权当备份
    第四篇:java读取Excel简单模板
    测试驱动android
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3708038.html
Copyright © 2011-2022 走看看