善意的投票&小M的作物 题解
善意的投票:
因为只有\(2\)种意愿,不妨让想睡午觉的和源点连边,让不想睡午觉的和汇点连边。对于每一对好朋友,在他们之间连边。那么只要源点和汇点还联通,就存在一对好友是冲突的,我们现在要做的就是删去最少的边,使得源点和汇点孤立,问题转化为最小割,用最大流求解即可。
#include <bits/stdc++.h>
int n,m;
int S,T;
int head[200000],tot=1;
int cur[200000];
int deep[200000];
std::queue<int>q;
struct edge{
int to;
int nxt;
int flow;
}e[200000];
void add(int x,int y,int flow){
e[++tot]={y,head[x],flow};
head[x]=tot;
e[++tot]={x,head[y],0};
head[y]=tot;
}
bool bfs(){
memset(deep,0,sizeof deep);
deep[S]=1;
q.push(S);
while(!q.empty()){
int X=q.front();
q.pop();
for(int i=head[X];i;i=e[i].nxt){
int y=e[i].to;
if(!deep[y]&&e[i].flow){
deep[y]=deep[X]+1;
q.push(y);
}
}
}
return deep[T];
}
int dfs(int x,int flow){
if(x==T||!flow)
return flow;
int Flow=0;
for(int &i=cur[x];i;i=e[i].nxt){
int y=e[i].to;
if(e[i].flow&&deep[y]==deep[x]+1){
if(int w=dfs(y,std::min(flow,e[i].flow))){
e[i].flow-=w;
e[i^1].flow+=w;
Flow+=w;
flow-=w;
if(!flow)
break;
}
}
}
return Flow;
}
void dinic(){
int maxflow=0;
while(bfs()){
memcpy(cur,head,sizeof head);
while(int w=dfs(S,0x3f3f3f3f))
maxflow+=w;
}
printf("%d\n",maxflow);
}
main(){
scanf("%d%d",&n,&m);
S=n+1;T=S+1;
for(int i=1,x;i<=n;++i){
scanf("%d",&x);
if(x)add(i,T,1);
else add(S,i,1);
}
for(int i=1,x,y;i<=m;++i){
scanf("%d%d",&x,&y);
add(x,y,1);
add(y,x,1);
}
dinic();
return 0;
}
再考虑小\(M\)的作物,按照之前的做法,对于每种作物,向源点和汇点分别连对应价值流量大小的边,考虑那些组合收益,假设我们需要获得那些作物在\(A\)中的收益,那么当组合中的所有点都和\(B\)断开后,我们才能保留这条边,所以我们可以这样连边:源点到这个点对应的点\(x\),流量为组合中的作物都种在\(A\)的价值,这个点向所有组合中的点连边,边权都为\(\infty\)。组合中的作物都对这个点对应的点\(x'\)连边,流量为\(\infty\),\(x'\)向汇点连边,流量为组合都种在\(B\)的价值。

问题得解。
#include <bits/stdc++.h>
#define int long long
int n,kind,S=1,T=2;
int ans;
int head[1000001],tot=1;
int cur[1000000];
int deep[5001];
struct edge{
int to,nxt,flow;
}e[4000000];
std::queue<int>q;
void add(int x,int y,int flow){
e[++tot]={y,head[x],flow};
head[x]=tot;
e[++tot]={x,head[y],0};
head[y]=tot;
}
bool bfs(){
while(!q.empty())q.pop();
memset(deep,-1,sizeof deep);
deep[S]=0;
for(int i=0;i<=tot;++i)
cur[i]=head[i];
q.push(S);
while(!q.empty()){
int X=q.front();
q.pop();
for(int i=head[X],y;i;i=e[i].nxt){
y=e[i].to;
if(deep[y]<0&&e[i].flow){
deep[y]=deep[X]+1;
q.push(y);
if(y==T)
return 1;
}
}
}
return 0;
}
int dfs(int x,int flow){
if(x==T||!flow)
return flow;
int Flow=0;
for(int &i=cur[x],y;i;i=e[i].nxt){
y=e[i].to;
if(e[i].flow&&deep[y]==deep[x]+1){
if(int w=dfs(y,std::min(flow,e[i].flow))){
e[i].flow-=w;
e[i^1].flow+=w;
Flow+=w;
flow-=w;
if(!flow)break;
}
}
}
if(!flow)
deep[x]=-1;
return Flow;
}
void dinic(){
while(bfs())
ans-=dfs(S,1e9);
printf("%lld\n",ans);
}
main(){
scanf("%lld",&n);
for(int i=1,x;i<=n;++i){
scanf("%lld",&x);
add(S,i+2,x);
ans+=x;
}
for(int i=1,x;i<=n;++i){
scanf("%lld",&x);
add(i+2,T,x);
ans+=x;
}
scanf("%d",&kind);
for(int i=1,th,valueA,valueB;i<=kind;++i){
scanf("%lld%lld%lld",&th,&valueA,&valueB);
ans+=valueA+valueB;
add(S,n+2+i,valueA);
add(n+2+i+kind,T,valueB);
for(int j=1,x;j<=th;++j){
scanf("%lld",&x);
add(n+2+i,2+x,1e6);
add(2+x,n+2+i+kind,1e6);
}
}
dinic();
return 0;
}
善意的投票&小M的作物 题解的更多相关文章
- luogu P1361 小M的作物
题目链接 luogu P1361 小M的作物 题解 源汇点为A,B 向种子连边,容量为价值,每个种子能与A或B联通,考虑最小割 用建边的总流量减去最小割就是答案 相同利益的时候新建节点,由额外利益构成 ...
- 「SHOI2007」「Codevs2341」 善意的投票(最小割
2341 善意的投票 2007年省队选拔赛上海市队选拔赛 时间限制: 5 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 幼儿园里有n个小朋 ...
- 洛谷 P1361 小M的作物 解题报告
P1361 小M的作物 题目描述 小M在MC里开辟了两块巨大的耕地\(A\)和\(B\)(你可以认为容量是无穷),现在,小\(P\)有\(n\)中作物的种子,每种作物的种子有1个(就是可以种一棵作物) ...
- C++之路进阶——bzoj1934(善意的投票)
F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...
- BZOJ 1934: [Shoi2007]Vote 善意的投票 最小割
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnl ...
- BZOJ 3438: 小M的作物( 最小割 )
orz出题人云神... 放上官方题解... 转成最小割然后建图跑最大流就行了... ---------------------------------------------------------- ...
- 1934: [Shoi2007]Vote 善意的投票
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 1174 Solved: 723[Submit][S ...
- 【BZOJ1934】善意的投票(网络流)
[BZOJ1934]善意的投票(网络流) 题面 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己 ...
- BZOJ 3438 小M的作物 & BZOJ 1877 [SDOI2009]晨跑
我由衷地为我的朋友高兴.哈哈,yian,当你nick name破百上千时,再打“蒟蒻”就会被打的. 好的,说正事吧.请注意,这还是题解.但我发现,网络流实在是太套路了(怪不得这两年几乎销声匿迹).我们 ...
随机推荐
- 【学习笔记:Python-网络编程】Socket 之初见
Socket 是任何一种计算机网络通讯中最基础的内容.当你在浏览器地址栏中输入一个地址时,你会打开一个套接字,可以说任何网络通讯都是通过 Socket 来完成的. Socket 的 python 官方 ...
- MES系统的模型结构和主要功能(二)
上一节,我们主要说了Mes系统是什么,以及它的特点和难点,本节,再来讨论一下一个合格的MES系统的模型结构和基本功能. 现代工厂的快速发展,对MES系统提出了更高的要求,其必须满足范围广泛的任务要求, ...
- qt获取指定目录下符合条件的文件路径
1)设置名称过滤器 QDir * dir = new QDir(路径); QStringList filter; Filter << QStringLiteral(“筛选的文件条件,如.x ...
- CF #635D Xenia and Colorful Gems 枚举+二分
Xenia and Colorful Gems 题意 给出三个数组,在每个数组中选择一个数字x,y,z,,使得\((x-y)^2+(y-z)^2+(x-z)^2\)最小. 思路 我们假设x<=y ...
- Codeforces Round #635C Linova and Kingdom 思维
Linova and Kingdom 题意 现在有一颗n个节点的树,每个节点是一个城市,现在要选出k个城市作为工业城市,其他城市作为旅游城市,现在每个工业城市要派出一名特使前往根节点,每个特使的幸福度 ...
- [hdu5360]贪心
题意:一个人想邀请n个人出去玩,假设当前同意和他一起去的人数为cnt,那么他去邀请i的时候,i同意的条件是L[i]<=cnt<=R[i],L[i],R[i]是给定的,问怎样安排邀请顺序,使 ...
- [hdu4911]逆序对相关
思路:由于只能交换相邻的数,所以每次最多减小1个逆序对(且如果存在逆序对那么肯定可以减小1个)!于是乎..就是统计逆序对的裸题了.树状数组或归并都行. #pragma comment(linker, ...
- 在ef core中使用postgres数据库的全文检索功能实战
起源 之前做的很多项目都使用solr/elasticsearch作为全文检索引擎,它们功能全面而强大,但是对于较小的项目而言,构建和维护成本显然过高,尤其是从关系数据库/文档数据库到全文检索引擎的数据 ...
- 学习python的第一天,python的简单知识
python 是现如今比较火的一种编程语言.在抱着试试的态度我来进行学习下python.要学习python 要先进行环境的安装. 下面是下载链接:https://pan.baidu.com/s/1PW ...
- java ->IO流_打印流
打印流的概述 打印流添加输出数据的功能,使它们能够方便地打印各种数据值表示形式. 打印流根据流的分类: 永远不会抛出IO异常 l 字节打印流 PrintStream l 字符打印流 Print ...