zoukankan      html  css  js  c++  java
  • 洛谷P4014 分配问题(费用流)

    题目描述

    有 nn 件工作要分配给 nn 个人做。第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij 。试设计一个将 nn 件工作分配给 nn 个人做的分配方案,使产生的总效益最大。

    输入输出格式

    输入格式:

    文件的第 11 行有 11 个正整数 nn ,表示有 nn 件工作要分配给 nn 个人做。

    接下来的 nn 行中,每行有 nn 个整数 c_{ij}cij ​​,表示第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij 。

    输出格式:

    两行分别输出最小总效益和最大总效益。

    输入输出样例

    输入样例#1: 复制
    5
    2 2 2 1 2
    2 3 1 2 4
    2 0 1 1 1
    2 3 4 3 3
    3 2 1 2 1
    输出样例#1: 复制
    5
    14

    说明

    1 leq n leq 1001n100

    一个人只能修一个工件

    又是一道挺裸的费用流

    从S向每个工人连容量为1,费用为0的边

    从每个工件向T连容量为1,费用为0的边

    从每个工人向每个工件连容量为1,费用为c[i][j]的边

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define AddEdge(x,y,z,f) add_edge(x,y,z,f),add_edge(y,x,-z,0)
    using namespace std;
    const int INF=1e8+10;
    const int MAXN=1e4+10;
    int N,M,S,T;
    int C[MAXN][MAXN];
    struct node
    {
        int u,v,w,f,nxt;
    }edge[MAXN];
    int head[MAXN],num=2;
    inline void add_edge(int x,int y,int z,int f)
    {
        edge[num].u=x;
        edge[num].v=y;
        edge[num].w=z;
        edge[num].f=f;
        edge[num].nxt=head[x];
        head[x]=num++;
    }
    int dis[MAXN],vis[MAXN],Pre[MAXN];
    bool SPFA()
    {
        memset(dis,0xf,sizeof(dis));
        memset(vis,0,sizeof(vis));
        queue<int>q;
        q.push(S);
        dis[S]=0;
        while(q.size()!=0)
        {
            int p=q.front();q.pop();
            vis[p]=0;
            for(int i=head[p];i!=-1;i=edge[i].nxt)
            {
                if(edge[i].f&&dis[edge[i].v]>dis[p]+edge[i].w)
                {
                    dis[edge[i].v]=dis[p]+edge[i].w;
                    Pre[edge[i].v]=i;
                    if(!vis[edge[i].v])
                        vis[edge[i].v]=1,q.push(edge[i].v);
                }
            }
        }
        return dis[T]<INF;
    }
    int F()
    {
        int nowflow=INF;
        for(int now=T;now!=S;now=edge[Pre[now]].u)
            nowflow=min(nowflow,edge[Pre[now]].f);
        for(int now=T;now!=S;now=edge[Pre[now]].u)
            edge[Pre[now]].f-=nowflow,
            edge[Pre[now]^1].f+=nowflow;
        return nowflow*dis[T];
    }
    void MCMF()
    {
        int ans=0;
        while(SPFA())
            ans+=F();
        printf("%d
    ",abs(ans));
    }
    int main()
    {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #endif
        memset(head,-1,sizeof(head));
        scanf("%d",&N);
        S=0;T=N<<1|1;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                scanf("%d",&C[i][j]);
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                AddEdge(i,j+N,C[i][j],1);
        for(int i=1;i<=N;i++)
            AddEdge(S,i,0,1),AddEdge(i+N,T,0,1);
        MCMF();
        memset(head,-1,sizeof(head));
        num=2;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                AddEdge(i,j+N,-C[i][j],1);
        for(int i=1;i<=N;i++)
            AddEdge(S,i,0,1),AddEdge(i+N,T,0,1);
        MCMF();
        return 0;
    }
  • 相关阅读:
    Codeforces Round #358 (Div. 2)
    Codeforces Round #357 (Div. 2)
    Codeforces Round #356 (Div. 2)
    第11章例题(紫书)
    第10章例题(紫书)
    Codeforces Round #354 (Div. 2)
    2016百度之星
    BestCoder 1st Anniversary
    BestCoder Round #41
    BestCoder Round #40
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8544383.html
Copyright © 2011-2022 走看看