P4014 分配问题(网络流24题 最大最小费用流)

题目描述

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

输入格式

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

接下来的 n 行中,每行有 n 个整数 cij???,表示第 i 个人做第 j件工作产生的效益为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 1001≤n≤100

一个人只能修一个工件


  1 #include<bits/stdc++.h>
  2 #define N 505
  3 #define INF LLONG_MAX/2
  4 using namespace std;
  5 typedef struct
  6 {
  7     int u,v;
  8     long long flow,cost;//flow 是流量 cost是花费
  9 }ss;
 10 ss edg[N*N];
 11 vector<int>edges[N];//记录每个点 所有和他相连的边吗
 12 int now_edges=0;//等同于sumedg
 13
 14 void addedge(int u,int v,long long flow,long long cost)
 15 {
 16     edges[u].push_back(now_edges);
 17     edg[now_edges++]=(ss){u,v,flow,cost};
 18     edges[v].push_back(now_edges);
 19     edg[now_edges++]=(ss){v,u,0,-cost};
 20 }
 21
 22 bool spfa(int s,int t,long long &flow,long long &cost)
 23 {
 24 //    printf("%lld %lld\n",flow,cost);
 25     long long dis[N];
 26     for(int i=0;i<N;i++)dis[i]=INF;
 27     dis[s]=0;
 28     int vis[N]={0};
 29     vis[s]=1;
 30     queue<int>q;
 31     q.push(s);
 32     int pre[N]={0}; // 记录费用流路径的 记录前驱用的  通过前驱找到路径 然后最后会修改这个路径
 33     long long  maxflow[N]={0};
 34     maxflow[s]=INF;
 35
 36     while(!q.empty())
 37     {
 38         int now=q.front();
 39         q.pop();
 40         vis[now]=0;
 41
 42         int Size=edges[now].size();
 43         for(int i=0;i<Size;i++)
 44         {
 45             ss &e=edg[edges[now][i]];
 46
 47             if(e.flow>0&&dis[e.v]>dis[now]+e.cost)
 48             {
 49                 dis[e.v]=dis[now]+e.cost;
 50                 pre[e.v]=edges[now][i];
 51                 maxflow[e.v]=min(maxflow[now],e.flow);
 52
 53                 if(!vis[e.v])
 54                 {
 55                     q.push(e.v);
 56                     vis[e.v]=1;
 57                 }
 58             }
 59         }
 60     }
 61
 62     if(dis[t]==INF)return false;
 63
 64     flow+=maxflow[t];
 65     cost+=dis[t]*maxflow[t];
 66
 67     long long now=t;
 68     while(now!=s)
 69     {
 70         edg[pre[now]].flow-=maxflow[t];
 71         edg[pre[now]^1].flow+=maxflow[t];
 72         now=edg[pre[now]].u;
 73     }
 74
 75
 76     return true;
 77 }
 78
 79 void mcmf(int s,int t,long long &flow,long long &cost)
 80 {
 81     while(spfa(s,t,flow,cost)); //一次只能找到一条路径  但是费用流不止一条路径 把全部跑出来
 82 }
 83 void init()
 84 {
 85     now_edges=0;
 86     for(int i=0;i<N;i++)edges[i].clear();
 87 }
 88
 89 int c[505][505];
 90
 91 int main()
 92 {
 93     int n,s,t;
 94     scanf("%d",&n);
 95     s=2*n+1;
 96     t=2*n+2;
 97     for(int i=1;i<=n;i++)
 98     for(int j=1;j<=n;j++)
 99     {
100         scanf("%d",&c[i][j]);
101     }
102
103
104     for(int i=1;i<=n;i++)
105     for(int j=1;j<=n;j++)addedge(i,j+n,1,c[i][j]);//最短路跑 正边权跑最小费用
106
107     for(int i=1;i<=n;i++)
108     {
109         addedge(s,i,1,0);
110         addedge(i+n,t,1,0);
111     }
112     long long flow=0,cost=0;
113     mcmf(s,t,flow,cost);
114     printf("%lld\n",cost);
115
116     init();
117
118     for(int i=1;i<=n;i++)
119     for(int j=1;j<=n;j++)addedge(i,j+n,1,-c[i][j]);//负边权跑最大费用
120
121     for(int i=1;i<=n;i++)
122     {
123         addedge(s,i,1,0);
124         addedge(i+n,t,1,0);
125     }
126     flow=0;
127     cost=0;
128     mcmf(s,t,flow,cost);
129     printf("%lld\n",-cost);
130     return 0;
131 }

原文地址:https://www.cnblogs.com/sylvia1111/p/12244921.html

时间: 2024-11-11 14:04:54

P4014 分配问题(网络流24题 最大最小费用流)的相关文章

网络流24题 -No.18 分配问题

问题描述 有 n件工作要分配给 n个人做.第 i 个人做第 j 件工作产生的效益为c[i,j] .试设计一个将n 件工作分配给 n个人做的分配方案,使产生的总效益最大. 编程任务对于给定的 n件工作和 n 个人,计算最优分配方案和最差分配方案. 数据输入输入的第 1 行有 1 个正整数 n,表示有 n件工作要分配给 n 个人做.接下来的 n 行中,每行有 n 个整数c[i,j],1≤i≤n,1≤j≤n,表示第 i 个人做第 j 件工作产生的效益为c[i,j] . 结果输出程序运行结束时,输出最小

[网络流24题] 分配问题

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 个

【网络流24题】分配问题(二分图最佳匹配)(费用流)

[网络流24题]分配问题 2014年3月11日1,8720 题目描述 Description 有n件工作要分配给n个人做.第i 个人做第j 件工作产生的效益为ij c .试设计一个将n件工作分配给n个人做的分配方案,使产生的总效益最大.«编程任务:对于给定的n件工作和n个人,计算最优分配方案和最差分配方案. 输入描述 Input Description 第1 行有1 个正整数n,表示有n件工作要分配给n 个人做.接下来的n 行中,每行有n 个整数 cij ,1≤i≤n,1≤j≤n,表示第i 个人

「网络流24题」 18. 分配问题

「网络流24题」 18. 分配问题 <题目链接> 费用流其实是可以做这题的. 但这篇主要说一下二分图最佳完美匹配--Kuhn-Munkres(KM)算法. 工作是X部,费用是Y部,边权为工作效益. 通过X部减去/Y部增加增广路上的松弛量,修改「顶标」(又称标杆). 初始顶标:X部点:最大权出边的边权:Y部点:0. 跑出来后,所有顶标和是最大效益. 所有边取负,跑出来的和的相反数是最小效益. 具体请看此篇题解. KM写法 #include <algorithm> #include &

网络流24题之分配问题

题目链接:传送门 这道题和运输问题也是贼相似的,几乎一模一样 详细见网络流24题之分配问题 #include<bits/stdc++.h> using namespace std; typedef long long ll; int read(){ int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0'&&c<='9') x=

BZOJ_1221_ [HNOI2001]_软件开发(网络流24题,最小费用流)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1221 n天,每天需要r个毛巾,用完以后可以洗,要么花fa洗a天,要么花fb洗b天,毛巾不够了可以话f买一个,问最少需要多少钱. 分析 把每天拆成两个点:x[i]表示第i天的脏毛巾,y[i]表示第i天要用的毛巾. 1.s向x[i]连弧,容量为r[i],花费为0,表示每天会用脏r[i]条毛巾. 2.x[i]向x[i+1]连弧(注意边界),容量为INF,花费为0,表示把第i天的脏毛巾搁置到第i+1

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

「网络流24题」 题目列表

「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分图最小路径覆盖 <3> 4 魔术球问题 <4> 5 圆桌问题 <5> 6 最长递增子序列问题 <6> 7 试题库问题 <7> 8 机器人路径规划问题 <8> 9 方格取数问题 二分图最大点权独立集 <9> 10 餐巾计划问题

网络流24题 部分总结

网络流24题 部分总结 慢慢写吧... 以前做过一些了: 然后发现也做了不少了,集中写一下. 警告: 题目按照随机顺序排列. 文章中只有建模的方法. 最小路径覆盖问题 http://cogs.pro:8080/cogs/problem/problem.php?pid=728 题目即题解... // It is made by XZZ #include<cstdio> #include<algorithm> #include<cstring> #define File #