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
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; }