网络流二十四题 分配问题

            分配问题

题目描述

有 nn 件工作要分配给 nn 个人做。第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij? 。试设计一个将 nn 件工作分配给 nn 个人做的分配方案,使产生的总效益最大。

输入输出格式

输入格式:

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

接下来的 nn 行中,每行有 nn 个整数 c_{ij}cij? ??,表示第 ii 个人做第 jj 件工作产生的效益为 c_{ij}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≤n≤100

一个人只能修一个工件




2018.7.5测试T3

当时打出了最小费用,却没敢做,打了10分的搜索暴力(;′⌒`)

其实挺简单的

二分图,左边是人,右边的工作,

建立一个超级源点,一个超级汇点

建的边流量都是1(一个人只能修一个工件)

与源点或汇点相连的费用全是0

人与工作之间的费用是他们之间的效益

一个最大一个最小,取反一下就可以辣

 1 #include <iostream>
 2 #include <queue>
 3 #include <cstring>
 4 #include <cstdio>
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7
 8 int n,s,t;
 9 int a[101][101];
10 struct node{
11     int u,v,flow,spend,next;
12 }e[100100];
13 int head[100100],tot=1;
14 int from[100100],vis[100100],dis[100100];
15 int ans;
16
17 void add_node(int a,int b,int f,int s) {
18     e[++tot]=(node){a,b,f,s,head[a]};
19     head[a]=tot;
20 }
21 bool SPFA() {
22     memset(dis,inf,sizeof(dis));
23     memset(vis,0,sizeof(vis));
24     queue<int> q;
25     q.push(s);
26     dis[s]=0;
27     while(!q.empty()) {
28         int x=q.front();
29         q.pop();vis[x]=0;
30         for(int i=head[x];i;i=e[i].next) {
31             int v=e[i].v;
32             int u=e[i].u;
33             int f=e[i].flow;
34             int s=e[i].spend;
35             if(dis[u]+s < dis[v]&& f>0) {
36                 dis[v]=dis[u]+s;
37                 from[v]=i;
38                 if(!vis[v]) {
39                     vis[v]=1;
40                     q.push(v);
41                 }
42             }
43         }
44     }
45     return dis[t]!=inf;
46
47 }
48 void work() {
49     int mn=inf;
50     for(int i=t;i!=s;i=e[from[i]].u)
51         mn=min(mn,e[from[i]].flow);
52     for(int i=t;i!=s;i=e[from[i]].u) {
53         e[from[i]].flow-=mn;
54         e[from[i]^1].flow+=mn;
55         ans+=mn*e[from[i]].spend;
56     }
57 }
58
59 int main()
60 {
61     scanf("%d",&n);
62        //1到n代表人
63        //n+1到n+n代表工作
64        //0代表超级源点
65        //n+n+1代表超级汇点
66     for(int i=1;i<=n;++i)
67         for(int j=1;j<=n;++j)
68             scanf("%d",&a[i][j]),add_node(i,j+n,1,a[i][j]),add_node(j+n,i,0,-a[i][j]);
69     s=0,t=n+n+1;
70     for(int i=1;i<=n;++i)add_node(s,i,1,0),add_node(i,s,0,0),add_node(n+i,t,1,0),add_node(t,n+i,0,0);
71
72         //建边后直接套板子
73     while(SPFA()) work();
74     printf("%d\n",ans);
75
76     //清空再来一遍, 存一遍的骚操作蒟蒻表示掌握不来╮(╯▽╰)╭
77     memset(e,0,sizeof(e));
78     memset(head,0,sizeof(head));
79     memset(from,0,sizeof(from));
80     memset(vis,0,sizeof(vis));
81     memset(dis,0,sizeof(dis));
82     ans=0;tot=1;
83
84         //基本就是上面在复制一遍
85     for(int i=1;i<=n;++i)
86         for(int j=1;j<=n;++j)
87             add_node(i,j+n,1,-a[i][j]),add_node(j+n,i,0,a[i][j]);
88     s=0,t=n+n+1;
89     for(int i=1;i<=n;++i)add_node(s,i,1,0),add_node(i,s,0,0),add_node(n+i,t,1,0),add_node(t,n+i,0,0);
90     while(SPFA()) work();
91     printf("%d",-ans);
92     return 0;
93 }

原文地址:https://www.cnblogs.com/lovedsr/p/9269684.html

时间: 2024-07-30 13:22:43

网络流二十四题 分配问题的相关文章

网络流二十四题

网络流二十四题 网络流是个好东西,希望我也会. 网络流?\(orz\ zsy!!!!!\) P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(dp(i)\)代表以\(i\)为起点的\(LIS\)是多少.转移太显然了 \[ dp(i)=max\{dp(j)\}+1,data[i]\le data[j] \] 想一想一个合法的\(LIS\)方案代表着什么,代表着它是由这个式子一个一个推出来的. 考虑一个数字只能用一次,那么我们直接拆成两个点\(

网络流二十四题之餐巾计划问题

题目传送门 这题的思路我觉得five20巨佬讲的已经非常清晰了,所以就推荐一下他的题解,我就只放代码了 //It is made by HolseLee on 7th Feb 2018 //Luogu.org P1251 #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<queue> #inc

网络流二十四题之魔术球问题

P2765 魔术球问题 题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.例如,在4 根柱子上最多可放11 个球. «编程任务: 对于给定的n,计算在n根柱子上最多能放多少个球. 输入输出格式 输入格式: 第1 行有1个正整数n,表示柱子数. 输出格式: 程序运行结束时,将n 根柱子上最

从零开始学android&lt;android事件的处理方式.二十四.&gt;

在android中一共有 多种事件,每种事件都有自己相对应的处理机制 如以下几种 1 单击事件 View.OnClickListener public abstract void onClick (View v) 单击组件时触发 2 单击事件 View.OnLongClickListener public abstract boolean onLongClick (View v) 长按组件时触发 3 键盘事件 View.OnKeyListener public abstract boolean

code第一部分:数组 第十四题 雨水问题

code第一部分:数组 第十四题 雨水问题 Given n non-negative integers representing an elevation map where the width of each bar is 1, computehow much water it is able to trap after raining.For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. 分析: 解决方案1 对于每个柱子,找到其左右两

实验二十四:SD卡模块

  驱动SD卡是件容易让人抓狂的事情,驱动SD卡好比SDRAM执行页读写,SD卡虽然不及SDRAM的麻烦要求(时序参数),但是驱动过程却有猥琐操作.除此此外,描述语言只要稍微比较一下C语言,描述语言一定会泪流满面,因为嵌套循环,嵌套判断,或者嵌套函数等都是它的痛.. 史莱姆模块是多模块建模的通病,意指结构能力非常脆弱的模块,暴力的嵌套行为往往会击垮模块的美丽身躯,好让脆弱结构更加脆弱还有惨不忍睹,最终搞垮模块的表达能力.描述语言预想驾驭SD卡,关键的地方就是如何提升模块的结构能力.简单而言,描述

攻城狮在路上(叁)Linux(二十四)--- linux设置开机挂载及镜像文件挂载

虽然可以手动进行文件系统的挂载,但是每次都手动挂载就会很麻烦,开机挂载的目的就是实现文件系统的自动挂载. 一.开机挂载:/etc/fstab及/etc/mtab 主要是通过修改/etc/fstab文件的配置来实现. fstab是开机时的设置,实际文件系统的挂载是记录到/etc/mtab和/proc/mounts这两个文件中. 1.系统挂载的限制: A.根目录/必须挂载,而且一定是最先挂载的,要先于其他mount point. B.其他挂载点必须为已新建的目录,可以任意指定. C.所有挂载点在同一

全栈JavaScript之路( 二十四 )DOM2、DOM3, 不涉及XML命名空间的扩展

(一)DocumentType 类型的变化新增三个属性: publicId,systemId,internalSubset(内部子集) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" [<!ELEMENT name (#PCDATA)>] > 通过, document.doc

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意