P4014 allocation in Luogu

Keywords: C++

Title Description

There are nn jobs to be assigned to nn individuals. The second is that the benefit of doing the jj job is C {ij} CIJ. Try to design a distribution scheme that assigns nn tasks to nn individuals, so as to maximize the total benefit.

I / O format

Input format:

 

There are 11 positive integers nn in line 11 of the file, indicating that there are nn jobs to be assigned to nn individuals.

In the next nn line, there are nn integers C {ij} CIJ in each line, indicating that the benefit of the second individual doing the work of the jj is C {ij} CIJ.

 

Output format:

 

The two lines output the minimum total benefit and the maximum total benefit respectively.

 

Example of input and output

Input example ා 1:copy
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
Output example:copy
5
14

Explain

1 \leq n \leq 1001≤n≤100

One person can only repair one workpiece

 

 

It's another pretty naked cost stream

From S to the side with capacity of 1 and cost of 0 for each worker

From each piece to the side with T connection capacity of 1 and cost of 0

From each worker to each workpiece, the capacity is 1, and the cost is 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\n",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;
}

Posted by plazz2000 on Sat, 04 Apr 2020 19:01:46 -0700