740. [网络流24题] 分配问题
★★ 输入文件:job.in
输出文件:
job.out
简单对比
时间限制:1 s 内存限制:128 MB
«问题描述:
有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为ij c 。试设计一个将n件工作分配给n个人做的分配方案,使产生的总效益最大。
«编程任务:
对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。«数据输入:
由文件job.in提供输入数据。文件的第1 行有1 个正整数n,表示有n件工作要分配给n 个人做。接下来的n 行中,每行有n 个整数ij c ,1≤i≤n,1≤j≤n,表示第i 个人做
第j件工作产生的效益为ij c 。
«结果输出:
程序运行结束时,将计算出的最小总效益和最大总效益输出到文件job.out中。输入文件示例 输出文件示例
job.in
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
job.out
5
14
数据范围
N<=100分析:
最小费用最大流和最大费油最大流 的裸题
实现 EK(貌似zkw更优)
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- using namespace std;
- const int N=210;
- const int inf=2e9;
- struct edge{int v,cap,cost,next;}e[N*N*2];int tot=1,head[N];
- int n,m,S,T,ans,a[N][N],dis[N],pre[N],q[N*N*2];bool vis[N];
- inline int read(){
- int x=0,f=1;char ch=getchar();
- // while(ch<'0'||ch>'9'){if(ch='-')f=-1;ch=getchar();}读入优化写错了,本地没检测出来。。。
- while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
- while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
- return x*f;
- }
- inline void add(int x,int y,int z,int cost){
- e[++tot].v=y;e[tot].cap=z;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot;
- e[++tot].v=x;e[tot].cap=0;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot;
- }
- inline bool spfa(int f){
- if(f)for(int i=S;i<=T;i++) dis[i]=inf,vis[i]=0;//min cost
- else for(int i=S;i<=T;i++) dis[i]=-inf,vis[i]=0;//max cost
- unsigned short h=0,t=1;q[t]=S;dis[S]=0;
- while(h!=t){
- int x=q[++h];vis[x]=0;
- for(int i=head[x];i;i=e[i].next){
- if(e[i].cap&&( (f&&dis[e[i].v]>dis[x]+e[i].cost)
- ||(!f&&dis[e[i].v]<dis[x]+e[i].cost) )){
- dis[e[i].v]=dis[x]+e[i].cost;
- pre[e[i].v]=i;
- if(!vis[e[i].v]){
- vis[e[i].v]=1;
- q[++t]=e[i].v;
- }
- }
- }
- }
- if(f) return dis[T]!=inf;
- else return dis[T]!=-inf;
- }
- inline int augment(){
- int flow=inf;
- for(int i=T;i!=S;i=e[pre[i]^1].v) flow=min(flow,e[pre[i]].cap);
- for(int i=T;i!=S;i=e[pre[i]^1].v){
- e[pre[i]].cap-=flow;
- e[pre[i]^1].cap+=flow;
- }
- return dis[T]*flow;
- }
- inline void init(){
- n=read();
- for(int i=1;i<=n;i++){
- for(int j=1;j<=n;j++){
- a[i][j]=read();
- }
- }
- }
- inline void mapping(){
- S=0,T=n<<1|1;
- tot=1;memset(head,0,sizeof head);
- for(int i=1;i<=n;i++) add(S,i,1,0);
- for(int i=1;i<=n;i++) add(i+n,T,1,0);
- for(int i=1;i<=n;i++){
- for(int j=1;j<=n;j++){
- add(i,j+n,1,a[i][j]);
- }
- }
- }
- inline void work(){
- mapping();
- while(spfa(1)) ans+=augment();
- printf("%d\n",ans);
- mapping();ans=0;
- while(spfa(0)) ans+=augment();
- printf("%d\n",ans);
- }
- int main(){
- freopen("job.in","r",stdin);
- freopen("job.out","w",stdout);
- init();
- work();
- return 0;
- }