zoukankan      html  css  js  c++  java
  • CF546E

    这题并不是太难

    首先题目我们将每个城市拆点,由源点向一端连容量为初始人数的边,由另一端向汇点连容量为最后人数的边,然后按照题目要求从一端向另一端连容量无穷大的边

    这样跑出最大流之后我们只需比较这个流量与总人数是否相等就知道是否合法了

    至于输出方案,一个点向另一个点的所有流量都会体现在反向边上,因此我们只需最后统计反向边即可

    贴代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    const int inf=0x3f3f3f3f;
    struct Edge
    {
        int nxt;
        int to;
        int val;
    }edge[500005];
    int head[5005];
    int dis[5005];
    int cur[5005];
    int v0[5005],v1[5005];
    int re[105][105];
    int cnt=1;
    int n,m;
    int st,ed;
    int sum1=0,sum2=0;
    void add(int l,int r,int w)
    {
        edge[cnt].nxt=head[l];
        edge[cnt].to=r;
        edge[cnt].val=w;
        head[l]=cnt++;
    }
    void dadd(int l,int r,int w)
    {
        add(l,r,w),add(r,l,0);
    }
    int ide(int x)
    {
        return x&1?x+1:x-1;
    }
    bool bfs()
    {
        memset(dis,0,sizeof(dis));
        memcpy(cur,head,sizeof(head));
        dis[st]=1;
        queue <int> M;
        M.push(st);
        while(!M.empty())
        {
            int u=M.front();
            M.pop();
            for(int i=head[u];i;i=edge[i].nxt)
            {
                int to=edge[i].to;
                if(!dis[to]&&edge[i].val)dis[to]=dis[u]+1,M.push(to);
            }
        }
        return dis[ed];
    }
    int dfs(int x,int lim)
    {
        if(x==ed)return lim;
        int ret=0;
        for(int i=cur[x];i;i=edge[i].nxt)
        {
            int to=edge[i].to;
            if(dis[to]==dis[x]+1&&edge[i].val)
            {
                int temp=dfs(to,min(lim,edge[i].val));
                if(temp)
                {
                    ret+=temp,lim-=temp;
                    edge[i].val-=temp,edge[ide(i)].val+=temp;
                    if(!lim)break;
                }
            }
        }
        return ret;
    }
    int dinic()
    {
        int ans=0;
        while(bfs())ans+=dfs(st,inf);
        return ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        st=2*n+1,ed=2*n+2;
        for(int i=1;i<=n;i++)scanf("%d",&v0[i]),dadd(st,i,v0[i]),sum1+=v0[i];
        for(int i=1;i<=n;i++)scanf("%d",&v1[i]),dadd(i+n,ed,v1[i]),sum2+=v1[i];
        if(sum1!=sum2){printf("NO
    ");return 0;}
        for(int i=1;i<=n;i++)dadd(i,i+n,inf);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            dadd(x,y+n,inf),dadd(y,x+n,inf);
        }    
        int t=dinic();
        if(t==sum1)
        {
            printf("YES
    ");
            for(int i=1;i<=n;i++)
            {
                for(int j=head[i];j;j=edge[j].nxt)
                {
                    int to=edge[j].to;
                    if(to>n)re[i][to-n]=edge[ide(j)].val;
                }
            }
            for(int i=1;i<=n;i++,printf("
    "))for(int j=1;j<=n;j++)printf("%d ",re[i][j]);
        }else printf("NO
    ");
        return 0;
    }
  • 相关阅读:
    zabbix监控部署(三)
    zabbix监控部署(二)
    zabbix监控部署(一)
    Docker安装mysql5.7
    Docker修改容器默认存储路径
    MySQL全量+增量备份脚本
    企业级Dokcer镜像仓库Harbor部署
    Linux环境pyhon3安装pyinstaller
    配置Hive元数据数据库为PostgreSQL
    Oracle 11gR2 RAC 添加节点
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11168926.html
Copyright © 2011-2022 走看看