• poj3426(网络流)


    题意:有n个机器加工计算机,有p个计算机零件,接下来输出n个机器加工计算机情况,2*p+1个数据,第一个是每小时最多生产计算机台数,接下来p个数是,可以从p个零件状态的计算机生产到后面p个零件状态的计算机。问最多一小时生产多少计算机。

    当然这里零件状态是这样定义的,0表示没有,1表示必须要,2表示可有可无(所以2可以无视)

    思路:

    当然是从零件全是0的计算机开始了。然而你忘了有2也是可以的,只要零件非1就行。(一个坑点)

    会想到有很多可以加工全非1的机器,和加工到全1的机器,那么就是一个多源点,多汇点的网络流,就要用一个超级源点,超级汇点。

    超级源点连接可以从零件全非1开始加工的机器,而可以加工到全为1的机器连接超级汇点(第一步

    那么下一步就是连接机器,看是否加工的半成品是否可以给下一个机器加工。只要每个零件对应不能同时一个0,一个1,即可。(第二步

    接下来就是求网络流最大流量了,这里用dinic算法模板就行。(第三步

    最后只要计算有流量的路径并输出即可。(最后一步

    最后想复杂了,以为要输出每条增广路径,最后wa了几发。。。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    struct node{
        int c,f;
    }mp[100][100];
    int sx,ex,n,m,cnt;
    int g[100][100];
    int step[100],ans,li,outline[100][5];
    //li记录流量路径条数,outline记录路径情况 
    
    bool bfs()//dinic--求层次网络 
    {
        memset(step,0,sizeof(step));
        step[sx]=1;
        queue<int> q;
        q.push(sx);
        while(!q.empty())
        {
            int p=q.front();
            q.pop();
            for(int i=0;i<=m+1;i++)
            {
                if(!step[i]&&mp[p][i].c-mp[p][i].f)
                {
                    step[i]=step[p]+1;
                    q.push(i);
                }
            }
        }
        return step[ex]!=0;
    }
    
    int dinic(int pos,int flow)//求出层次网络中所有增广路径流量 
    {
        int f=flow;
        if(pos==ex)
            return flow;
        for(int i=0;i<=m+1;i++)
        {
            if(mp[pos][i].c-mp[pos][i].f&&step[pos]+1==step[i])
            {
                int a=mp[pos][i].c-mp[pos][i].f;
                int t=dinic(i,min(a,flow));
                mp[pos][i].f+=t;
                mp[i][pos].f-=t;
                flow-=t;
            }
        }
        return f-flow;
    }
    
    void solve()//最大流 
    {
        while(bfs())
        {
            ans+=dinic(sx,inf);
        }
        return ;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(mp,0,sizeof(mp));
            sx=0,ex=m+1;//起点sx,终点ex 
            ans=0,li=0;
            for(int i=1;i<=m;i++)
                for(int j=0;j<=2*n;j++)
                    scanf("%d",&g[i][j]);
            for(int i=1;i<=m;i++)//判断是否可以连接超级源点或超级汇点 
            {
                int flag1=0,flag2=0;
                for(int j=1;j<=n;j++)
                {
                    if(g[i][j]==1)
                        flag1=1;
                    if(g[i][j+n]==0)
                        flag2=1;
                }
                if(!flag1)//连接超级源点 
                    mp[sx][i].c=g[i][0];
                if(!flag2)//连接超级汇点 
                    mp[i][ex].c=g[i][0];
            }
            for(int i=1;i<=m;i++)//判断是否可以两两工厂相连 
            {
                for(int j=1;j<=m;j++)
                {
                    if(i==j)
                        continue;
                    int flag=0;
                    for(int k=1;k<=n;k++)
                    {
                        if(g[i][k+n]+g[j][k]==1)
                        {
                            flag=1;
                            break;
                        }
                    }
                    if(flag)
                        continue;
                    mp[i][j].c=min(g[i][0],g[j][0]);
                }
            }
            solve();//求最大流 
            for(int i=1;i<=m;i++)//判断路是否有流量 
            {
                for(int j=1;j<=m;j++)
                {
                    if(mp[i][j].f>0)
                    {
                        li++;
                        outline[li][1]=i;
                        outline[li][2]=j;
                        outline[li][3]=mp[i][j].f;
                    }
                }
            }
            cout<<ans<<' '<<li<<endl;
            for(int i=1;i<=li;i++)
            {
                cout<<outline[i][1]<<' '<<outline[i][2]<<' '<<outline[i][3]<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    最大后验估计(MAP)
    mysql启动问题access denied for user 'root'@'localhost'(using password:YES)
    Median of Two Sorted Arrays-----LeetCode
    Two Sum-----LeetCode
    动态资源不缓存 filter
    过滤器 filter
    分页
    aop动态代理 事务 threadlocal
    ThreadLocal 开启事务
    数据库 元数据
  • 原文地址:https://www.cnblogs.com/xiongtao/p/11140399.html
Copyright © 2020-2023  润新知