【网络流24题】No.18 分配问题 (二分图最佳匹配 费用流|KM)

时间:2020-12-29 13:30:14

【题意】

  有 n 件工作要分配给 n 个人做。第 i 个人做第 j 件工作产生的效益为 cij 。 试设计一个将
n 件工作分配给 n 个人做的分配方案, 使产生的总效益最大。

输入文件示例
input.txt
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.txt
5
14

【分析】

  很裸的。。二分图最大权匹配。

  等一下可以打一下KM。。。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define Maxn 1010
#define INF 0xfffffff struct node
{
int x,y,f,o,c,next;
}t[Maxn*Maxn],tt[Maxn*Maxn];int len;
int first[Maxn]; int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;} void ins(int x,int y,int f,int c)
{
t[++len].x=x;t[len].y=y;t[len].f=f;t[len].c=c;
t[len].next=first[x];first[x]=len;t[len].o=len+;
t[++len].x=y;t[len].y=x;t[len].f=;t[len].c=-c;
t[len].next=first[y];first[y]=len;t[len].o=len-;
} int st,ed;
queue<int > q;
int dis[Maxn],pre[Maxn],flow[Maxn];
bool inq[Maxn];
bool bfs()
{
while(!q.empty()) q.pop();
memset(dis,,sizeof(dis));
memset(inq,,sizeof(inq));
q.push(st);dis[st]=;flow[st]=INF;inq[st]=;
while(!q.empty())
{
int x=q.front();
for(int i=first[x];i;i=t[i].next) if(t[i].f>)
{
int y=t[i].y;
if(dis[y]>dis[x]+t[i].c)
{
dis[y]=dis[x]+t[i].c;
pre[y]=i;
flow[y]=mymin(flow[x],t[i].f);
if(!inq[y])
{
inq[y]=;
q.push(y);
}
}
}
inq[x]=;q.pop();
}
if(dis[ed]>=INF-) return ;
return ;
} void output()
{
for(int i=;i<=len;i+=)
printf("%d->%d %d %d\n",t[i].x,t[i].y,t[i].f,t[i].c);
printf("\n");
} int max_flow()
{
int ans=,sum=;
while(bfs())
{
sum+=dis[ed]*flow[ed];
ans+=flow[ed];
int now=ed;
while(now!=st)
{
t[pre[now]].f-=flow[ed];
t[t[pre[now]].o].f+=flow[ed];
now=t[pre[now]].x;
}
}
return sum;
} int n; void init()
{
scanf("%d",&n);
st=*n+;ed=st+;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
int x;
scanf("%d",&x);
ins(i,j+n,,x);
}
for(int i=;i<=n;i++) ins(st,i,,),ins(i+n,ed,,);
} int main()
{
init();
for(int i=;i<=len;i++) tt[i]=t[i];
int ans;
ans=max_flow();
printf("%d\n",ans);
for(int i=;i<=len;i++) t[i]=tt[i];
for(int i=;i<=len;i++) t[i].c=-t[i].c;
ans=max_flow();
printf("%d\n",-ans);
return ;
}

【网络流24题】No.18 分配问题 (二分图最佳匹配 费用流|KM)

2016-11-06 21:03:56