• poj1149PIGS——网络最大流


    题目:http://poj.org/problem?id=1149

    不把猪圈当做点,而把顾客当作点,把猪当作边权(流量);

    因为猪圈中的猪可流动,所以共用一个猪圈的人互相连边;

    注意应该连成链的形式,来保证先后顺序。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    queue<int>q;
    int m,n,s[1005],head[150],ct=1,cur[150],hd[1005],inf=1e9,d[150],ans;
    bool sid[150][150];
    struct N{
        int to,next,w;
        N(int t=0,int n=0,int ww=0):to(t),next(n),w(ww) {}
    }edge[25000];
    bool in[150];
    void add(int x,int y,int z)
    {
        sid[x][y]=1;sid[y][x]=1;
        edge[++ct]=N(y,head[x],z);head[x]=ct;
        edge[++ct]=N(x,head[y],0);head[y]=ct;
    }
    int fd(int x,int y)
    {
        for(int i=head[y];i;i=edge[i].next)//此处为有向边,所以应找y边集中连到x的边! 
            if(edge[i].to==x)return i;
        return 0;
    }
    bool bfs()
    {
        memset(d,0,sizeof d);
        while(q.size())q.pop();
        d[0]=1;q.push(0);
        while(q.size())
        {
            int x=q.front();q.pop();
            for(int i=head[x];i;i=edge[i].next)
            {
                int u=edge[i].to;
                if(!d[u]&&edge[i].w)
                {
                    d[u]=d[x]+1;
                    q.push(u);
                }
            }
        }
        return d[n+1];
    }
    int dfs(int x,int f)
    {
        if(x==n+1)return f;
        int res=0;
        for(int i=cur[x];i;i=edge[i].next)
        {
            int u=edge[i].to;
            if(d[u]==d[x]+1&&edge[i].w)
            {
                int tmp=dfs(u,min(edge[i].w,f-res));
                edge[i].w-=tmp;
                edge[i^1].w+=tmp;
                res+=tmp;
                if(edge[i].w)cur[x]=i;
                if(res==f)return f;
            }
        }
        if(!res)d[x]=0;
        return res;
    }
    int main()
    {
        scanf("%d%d",&m,&n);
        for(int i=1;i<=m;i++)
            scanf("%d",&s[i]);
        for(int i=1;i<=n;i++)
        {
            int k,x;
            scanf("%d",&k);
            for(int j=1;j<=k;j++)
            {
                scanf("%d",&x);
                if(!hd[x]&&!in[i])hd[x]=i,in[i]=1,add(0,i,s[x]);
                else if(!hd[x]&&in[i])
                {
                    hd[x]=i;
                    int e=fd(i,0);
                    edge[e].w+=s[x];
    //                edge[e^1].w-=s[x];//!!!
                }
    //            if(!hd[x])hd[x]=i,add(0,i,s[x]);
                if(hd[x])
                {
                    if(!sid[hd[x]][i])//免重 
                        add(hd[x],i,inf);
                    hd[x]=i;//!!!成链 
                }
            }
            scanf("%d",&x);
            add(i,n+1,x);
        }
        while(bfs())
        {
            for(int i=0;i<=n+1;i++)cur[i]=head[i];
            ans+=dfs(0,inf);
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    经典分水岭算法的 C++ 实现
    一个简易的键盘按键测试程序
    工程优化方法中的“最速下降法”和“DFP拟牛顿法”的 C 语言实现
    基于哈夫曼编码的压缩解压程序(C 语言)
    博客选择:博客园 or CSDN
    Spring总结
    CSS总结
    EL表达式总结
    Jdbc总结
    hibernate总结
  • 原文地址:https://www.cnblogs.com/Zinn/p/8620297.html
Copyright © 2020-2023  润新知