洛谷P4014 分配问题(费用流)
2018-06-17 21:03:45来源:未知 阅读 ()
题目描述
有 nn 件工作要分配给 nn 个人做。第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij? 。试设计一个将 nn 件工作分配给 nn 个人做的分配方案,使产生的总效益最大。
输入输出格式
输入格式:
文件的第 11 行有 11 个正整数 nn ,表示有 nn 件工作要分配给 nn 个人做。
接下来的 nn 行中,每行有 nn 个整数 c_{ij}cij? ??,表示第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij? 。
输出格式:
两行分别输出最小总效益和最大总效益。
输入输出样例
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
5 14
说明
1 \leq n \leq 1001≤n≤100
一个人只能修一个工件
又是一道挺裸的费用流
从S向每个工人连容量为1,费用为0的边
从每个工件向T连容量为1,费用为0的边
从每个工人向每个工件连容量为1,费用为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; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Visual Studio 2019提示不能将const char*类型的值分配到con 2020-06-07
- 洛谷P1164->小A点菜 2020-05-18
- 洛谷P1907口算练习题 2020-03-24
- 结题报告--P5551洛谷--Chino的树学 2020-03-13
- 结题报告--洛谷P3915 2020-03-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash