• poj3436(拆点最大流)


    题意:给你p和n,p代表每台计算器需要几个部分组成,n代表有几个组装机器,接下来n行,每行第一个数代表这台机器能够每小时组装几台,剩下前三个数字表示使用这台机器需要的前置条件(0代表当前组装不能有这个部分,1代表得有,2代表无所谓),剩下三个数字表示使用这台机器后的组装有那几个部分,问你最多能组装多少台

    解题思路:首先最大流,建立一个超级源点,这个源点和所有前三个数字没有1的机器相连,建立一个超级汇点与所有后三个数字全为1的机器相连,中间所有的机器拆成两个点,边权为这个机器每小时的组装量,拆点的意义就是因为流过这个点的流量有限制

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=5050;
    struct sc
    {
        int x,y,w;
    }fna[maxn];
    struct node
    {
        int val;
        int x[15];
        int y[15];
    }a[100];
    struct Edge
    {
        int fa;
        int next;
        int to;
        int v;
        int w;
    }edge[maxn];
    int head[maxn],cnt;
    int pre[maxn],visit[maxn];
    int n,p,cot;
    int Start,End;
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];edge[cnt].to=v;edge[cnt].fa=u;edge[cnt].w=w;head[u]=cnt++;
        edge[cnt].next=head[v];edge[cnt].to=u;edge[cnt].fa=v;edge[cnt].w=0;head[v]=cnt++;
    }
    int bfs(int s,int e)
    {
        queue<int>q;
        memset(visit,0,sizeof(visit));memset(pre,-1,sizeof(pre));
        q.push(s);visit[s]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(edge[i].w<=0||visit[v])
                    continue;
                pre[v]=i;visit[v]=1;
                if(v==e)
                    return 1;
                q.push(v);
            }
        }
        return 0;
    }
    int EK()
    {
        int ans=0;
        int sub;
        while(bfs(Start,End))
        {
            sub=inf;
            int k=pre[End];
            while(k!=-1)
            {
                sub=min(sub,edge[k].w);
                k=pre[edge[k].fa];
            }
            k=pre[End];
            while(k!=-1)
            {
                edge[k].w-=sub;
                edge[k^1].w+=sub;
                k=pre[edge[k].fa];
            }
            ans+=sub;
        }
        return ans;
    }
    int main()
    {
        int vis[150][150];
        int flag;
        memset(head,-1,sizeof(head));cnt=0;
        memset(vis,0,sizeof(vis));
        scanf("%d%d",&p,&n);
        Start=0;End=2*n+1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i].val);
            for(int j=1;j<=p;j++)
                scanf("%d",&a[i].x[j]);
            for(int j=1;j<=p;j++)
                scanf("%d",&a[i].y[j]);
        }
        for(int i=1;i<=n;i++)
        {
            add(i,i+n,a[i].val);
            flag=0;
            for(int j=1;j<=p;j++)
                if(a[i].x[j]==1)
                    flag=1;
            if(flag==0)
                add(Start,i,a[i].val);
            flag=0;
            for(int j=1;j<=p;j++)
                if(a[i].y[j]!=1)
                    flag=1;
            if(flag==0)
                add(i+n,End,a[i].val);
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
        {
            flag=0;
            if(i==j)
                continue;
            for(int k=1;k<=p;k++)
            {
                if(a[j].x[k]==2)
                    continue;
                if(a[j].x[k]!=a[i].y[k])
                    flag=1;
            }
            if(flag==0)
            {
                add(i+n,j,a[i].val);
                vis[i+n][j]=1;
            }
        }
        int ans=EK();
        printf("%d ",ans);
        for(int i=1;i<=n;i++)
            for(int j=head[i+n];j!=-1;j=edge[j].next)
        {
            if(vis[i+n][edge[j].to]&&edge[j].w<a[i].val)
                cot++;
        }
        printf("%d
    ",cot);
        for(int i=1;i<=n;i++)
            for(int j=head[i+n];j!=-1;j=edge[j].next)
        {
            if(vis[i+n][edge[j].to]&&edge[j].w<a[i].val)
                printf("%d %d %d
    ",i,edge[j].to,a[i].val-edge[j].w);
        }
    }
    

      

  • 相关阅读:
    ubuntu 解决“无法获得锁 /var/lib/dpkg/lock -open (11:资源暂时不可用)”的方法
    解决VMware安装ubuntu16.04后无法全屏的问题
    力推:无限制下载神器aria2
    使用Pangolon在同一副图中,画出两个轨迹,比较误差
    Pangolin中opengl的混合(gl_blend)
    Ubuntu 16.04: How to install OpenCV
    ubuntu16.04下安装Eigen
    ubuntu16.04下安装Sophus
    svn删除账户信息
    javaweb乱码(tomcat服务器)
  • 原文地址:https://www.cnblogs.com/huangdao/p/9955284.html
Copyright © 2020-2023  润新知