【最小割】BZOJ2039- [2009国家集训队]employ人员雇佣
【题目大意】
给定n个人,每个人有一个佣金,i和j如果同时被雇佣会产生2*E(i,j)的效益,i和j如果一个被雇佣一个不被雇佣会产生E(i,j)的亏损,求最大收益。
【思路】
如果没有亏损,其实非常类似这道题:★
注意在这类问题里的最小割指代的是损失最小化。对于这道题,我们把S看作雇佣,T看作不雇佣。
首先对于每一个cost[i],从点i出发向汇点连一条流量为cost[i]的边。
对于每一对点(i,j),从S向点i和点j各连一条流量为E(i,j)的边,i和j之间连一条流量为2*E(i,j)的双向边。
ans最初等于矩阵里所有数的和。用ans减去最小割的时候,相当于割边没有被减去,而非割边被减去了。
如果割边是和S相连的,减去后,说明这个人雇佣了,付出了雇佣费,得到了一部分价值。
如果割边是和T相连的,减去后,说明没有雇佣,则没有付出雇佣费也没有得到价值。
那么对于一个被雇佣一个没有被雇佣呢?假设一个的割边与S连,一个的割边与Y连,那么必定会有中间的2*E(i,j)通过两者之间流走,所以他们之间的连边也必定成为割边。相当于得到了E[i,j]的价值,又丧失了2*E[i,j]的价值,总共丧失了E[i,j]的价值,符合题目意识。
dinic不知道为何写挂了,然后把程序里的函数一个一个拷贝到另一个空白界面重新编译了一下就过了,有毒quq没找到原来错在哪里。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define S 0
#define T n+1
using namespace std;
const int MAXN=+;
const int INF=0x7fffffff;
struct node
{
int to,pos,cap;
};
int m,n,ans=;
vector<node> E[MAXN*];
int dis[MAXN],e[MAXN][MAXN],sum[MAXN]; void addedge(int u,int v,int w)
{
E[u].push_back((node){v,E[v].size(),w});
E[v].push_back((node){u,E[u].size()-,});
} void init()
{
scanf("%d",&n);
int cost;
for (int i=;i<=n;i++)
{
scanf("%d",&cost);
addedge(i,T,cost);
}
int Eij;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
{
scanf("%d",&e[i][j]);
ans+=e[i][j];
if (i!=j)
{
sum[i]+=e[i][j];
addedge(i,j,*e[i][j]);
}
}
for (int i=;i<=n;i++) addedge(S,i,sum[i]);
} bool bfs()
{
memset(dis,-,sizeof(dis));
queue<int> que;
while (!que.empty()) que.pop();
que.push(S);
dis[S]=;
while (!que.empty())
{
int head=que.front();que.pop();
if (head==T) return true;
for (int i=;i<E[head].size();i++)
{
node tmp=E[head][i];
if (dis[tmp.to]==- && tmp.cap)
{
dis[tmp.to]=dis[head]+;
que.push(tmp.to);
}
}
}
return false;
} int dfs(int s,int e,int f)
{
if (s==e) return f;
int ret=;
for (int i=;i<E[s].size();i++)
{
node &tmp=E[s][i];
if (dis[tmp.to]==dis[s]+ && tmp.cap)
{
int delta=dfs(tmp.to,e,min(f,tmp.cap));
if (delta>)
{
tmp.cap-=delta;
E[tmp.to][tmp.pos].cap+=delta;
f-=delta;
ret+=delta;
if (f==) return ret;
}
else dis[tmp.to]=-;
}
}
return ret;
} void dinic()
{
while (bfs())
{
int f=dfs(S,T,INF);
if (f) ans-=f;else break;
}
printf("%d\n",ans);
} int main()
{
init();
dinic();
return ;
}
【最小割】BZOJ2039- [2009国家集训队]employ人员雇佣的更多相关文章
- bzoj2039: [2009国家集训队]employ人员雇佣(最小割)
传送门 膜一下大佬->这里 不难看出这是一个最小割的模型(然而我看不出来) 我们从源点向每一个点连边,容量为他能带来的总收益(也就是他能对其他所有经理产生的贡献) 然后从每一个点向汇点连边,容量 ...
- BZOJ2039 [2009国家集训队]employ人员雇佣
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2039 鉴于一开始看题如果不仔细是看不懂题目的,还是说一下题目大意 [题目大意]:给定n个人 ...
- 【BZOJ2039】[2009国家集训队]employ人员雇佣 最小割
[BZOJ2039][2009国家集训队]employ人员雇佣 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献 ...
- BZOJ_2039_[2009国家集训队]employ人员雇佣_ 最小割
BZOJ_2039_[2009国家集训队]employ人员雇佣_ 最小割 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作 ...
- 【BZOJ 2039】 2039: [2009国家集训队]employ人员雇佣 (最小割)
2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1511 Solved: 728 Descri ...
- BZOJ 2039: [2009国家集训队]employ人员雇佣
2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1369 Solved: 667[Submit ...
- bzoj 2039: [2009国家集训队]employ人员雇佣【最小割】
一开始在https://www.cnblogs.com/lokiii/p/10770919.html基础上连(i,j,b[i][j])建了个极丑的图T掉了--把dinic换成isap勉强能卡过 首先因 ...
- BZOJ 2039:[2009国家集训队]employ人员雇佣(最小割)
http://www.lydsy.com/JudgeOnline/problem.php?id=2039 题意:中文题意. 思路:一开始想着和之前做的最大权闭合图有点像,但是如果把边全部当成点的话,那 ...
- BZOJ 2039 / Luogu P1791 [2009国家集训队]employ人员雇佣 (最小割)
题面 BZOJ传送门 Luogu传送门 分析 考虑如何最小割建图,因为这仍然是二元关系,我们可以通过解方程来确定怎么建图,具体参考论文 <<浅析一类最小割问题 湖南师大附中 彭天翼> ...
随机推荐
- 2017ACM暑期多校联合训练 - Team 8 1008 HDU 6140 Hybrid Crystals (模拟)
题目链接 Problem Description Kyber crystals, also called the living crystal or simply the kyber, and kno ...
- centos6.5 导入matplotlib报错 No module named '_tkinter
1.解决方案 在centos系统下,导入matplotlib时,出现ImportError: No module named ‘_tkinter’的错误,首先 yum list installed | ...
- 爬虫实战--利用Scrapy爬取知乎用户信息
思路: 主要逻辑图:
- 爬虫--selenium
什么是selenium? 基本使用 from selenium import webdriver from selenium.webdriver.common.by import By from se ...
- Linux 官方镜像源汇总
原文链接 参考链接 1.企业贡献:阿里云开源镜像站: http://mirrors.aliyun.com 搜狐开源镜像站:http://mirrors.sohu.com网易开源镜像站:http:/ ...
- tensorflow.nn.bidirectional_dynamic_rnn()函数的用法
在分析Attention-over-attention源码过程中,对于tensorflow.nn.bidirectional_dynamic_rnn()函数的总结: 首先来看一下,函数: def bi ...
- 大美西安writeup
http://202.112.51.184:10080/ admin/admin 弱口令登入 发现注入 但是这个注入实在是不知道怎么利用.很蛋疼.后来get了一个姿势. 先-1让前面的不被下载然后后面 ...
- shell 监控磁盘使用率【转】
方案一: disks=(`df |sed 1d | awk '{print $1,$5}'|tr -d %`) len=${#disks[@]} ;i<=$len;i=i+));do ];the ...
- 清理oracle的用户中的日志垃圾以及修改sys用户的密码
清理oracle的用户中的日志垃圾1.进入:/opt/oracle/product/11g/network/admin目录2.注释掉listener.ora文件中的TRACE_LEVEL_LISTEN ...
- UNDO自我理解总结
[场景] 当在更新数据的时候,发现更新的值写错了,这时就需要将已经更新的地方恢复到原始数据. [基本概念] 在更新的过程中,Oracle会将原始的数据都放入到UNDO里,这样当以上情况发生后,就可以从 ...