poj2987 Firing[最小割]
求选最少点个数的最大权闭合子图。(板子题)
最小割入门题,什么都不想说,丢个别人题解地址就跑。
附加几点个人理解:与s相通的S点集是闭合子图,剩下的与t相通的T点集是其他的。任意一个割都保证了有一个闭合子图是S集。
然后是选最少点个数,考虑加入最大权时存在多个方案,选的点个数不同,既然各方案都是闭合的,那我全选也是闭合的,就会创出更多权值,与之前最大权矛盾,所以最大权一定点数唯一,选法唯一。那就直接从s点找残量网络,把他的点集都找一下,计下数即可。←这里有个原理,做最小割(最大流),而最大流算好后因为最小割必然满流,所以最小割对应的边残量为0,则dfs时就不遍历残量为0的边。←刚才又提到一个结论,一定存在一个最大流使得最小割在其中满流,这里口胡证明一下,防止以后我忘了:最大流做完后s所能到的所有点S集,以及另一T集之间,应当是有一些边满流的也就是残量为0的,不然就可继续增广,就不是最大流了,那这些边对应了一个割CUT[S,T],再由任意流小于等于任意割结论(打个比方,水流将流到割断的地方,而水流量小于等于容量,故得证)知,任意一个割大于等于这个最大流,即大于等于这个割,那这个割就是最小割,而她满流。证毕。
UPD:我现在看发现当时好像证的有点问题。。所以请不要信以为真,有空回来补详细的一些证明,当时只是个网络流初心者。
我还是太菜了啊。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline void inc(T&A,T B){A+=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*10+c-'0',c=getchar();return f?x=-x:x;
}
const int N=+,M=+;ll INF=1ll<<;
int Head[N],cur[N],Next[M<<],v[M<<],dis[N],vis[N],tot=,n,cnt,m,s,t;ll w[M<<]; inline void Addedge(int x,int y,ll z){
v[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
v[++tot]=x,Next[tot]=Head[y],Head[y]=tot,w[tot]=;
}
#define y v[j]
inline int bfs(){
queue<int> q;memset(dis,,sizeof dis),dis[s]=,q.push(s);
for(register int i=;i<=n+;++i)cur[i]=Head[i];
while(!q.empty()){
int x=q.front();q.pop();
for(register int j=Head[x];j;j=Next[j])if(w[j]&&!dis[y]){
dis[y]=dis[x]+,q.push(y);
if(y==t)return ;
}
}
return ;
}
ll dinic(int x,ll flow){
if(!flow||x==t)return flow;
ll rest=flow,k;
for(register int j=cur[x];j&&rest;cur[x]=j,j=Next[j])if(w[j]&&dis[y]==dis[x]+){
if(!(k=dinic(y,_min(rest,w[j]))))dis[y]=;
rest-=k,w[j]-=k,w[j^]+=k;
}
return flow-rest;
}
void dfs(int x){
for(register int j=Head[x];j;j=Next[j])if(w[j]&&!vis[y])vis[y]=,++cnt,dfs(y);
}
#undef y
int x,y;
ll maxflow,ans,z; int main(){//freopen("tmp.in","r",stdin);freopen("tmp.out","w",stdout);
read(n),read(m);s=n+,t=s+;
for(register int i=;i<=n;++i)read(z)>?(inc(ans,z),Addedge(s,i,z)):Addedge(i,t,-z);
for(register int i=;i<=m;++i)read(x),read(y),Addedge(x,y,INF);
while(bfs())inc(maxflow,dinic(s,INF));
ans-=maxflow;cnt=,vis[s]=,dfs(s);
printf("%d %lld\n",--cnt,ans);
return ;
}
Upd:今天被巨佬嘲讽了说我快读用位运算太慢。orzorzorzTQL
poj2987 Firing[最小割]的更多相关文章
- 【POJ 2987】Firing (最小割-最大权闭合子图)
裁员 [问题描述] 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误.给出每个人的贡献值和 ...
- POJ 2987 Firing【最大权闭合图-最小割】
题意:给出一个有向图,选择一个点,则要选择它的可以到达的所有节点.选择每个点有各自的利益或损失.求最大化的利益,以及此时选择人数的最小值. 算法:构造源点s汇点t,从s到每个正数点建边,容量为利益.每 ...
- POJ2987 Firing 【最大权闭合图】
POJ2987 Firing Description You've finally got mad at "the world's most stupid" employees o ...
- poj2987 Firing 最大权闭合子图 边权有正有负
/** 题目:poj2987 Firing 最大权闭合子图 边权有正有负 链接:http://poj.org/problem?id=2987 题意:由于金融危机,公司要裁员,如果裁了员工x,那么x的下 ...
- POJ 3308 Paratroopers(最小割EK(邻接表&矩阵))
Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...
- BZOJ 1391: [Ceoi2008]order [最小割]
1391: [Ceoi2008]order Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1509 Solved: 460[Submit][Statu ...
- BZOJ-2127-happiness(最小割)
2127: happiness(题解) Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1806 Solved: 875 Description 高一 ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- BZOJ3438 小M的作物(最小割)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=3438 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为 ...
随机推荐
- ApiDoc 后端接口注释文档的使用
前端和后端注释文档生成 前端和后端的 函数及api 说明文档生成总结,持续更新中 by Qzx 参考网址 jsDoc - 中文说明 jsDoc 使用教程 后台接口文档生成器 - APIDOC官网 ap ...
- Android测试之查看package和activity名称的方法
方法一:使用aapt //aapt是sdk自带的一个工具,在sdk\builds-tools\目录下 1.命令行中切换到aapt.exe目录执行:aapt dump badging + 路径 ...
- Xing: The Land Beyond — 从课堂到 Steam* 的卓越之旅
Xing:The Land Beyond 的诞生最初源于大学的一个关卡设计课程,之后才登录 Kickstarter* 平台,采用虚拟现实技术,并由 Sony* 带到电子娱乐展览会.这个设计任务本来计划 ...
- Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray)
Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. ...
- TensorFlow实战第五课(MNIST手写数据集识别)
Tensorflow实现softmax regression识别手写数字 MNIST手写数字识别可以形象的描述为机器学习领域中的hello world. MNIST是一个非常简单的机器视觉数据集.它由 ...
- 菜鸟系列k8s——k8s集群部署(2)
k8s集群部署 1. 角色分配 角色 IP 安装组件 k8s-master 10.0.0.170 kube-apiserver,kube-controller-manager,kube-schedul ...
- oracle查询表的结构
SELECT t.table_name,t.column_name,t.data_type||'('||t.data_length||')', t1.comments FROM User_Tab_Co ...
- Oracle表的Rowid字段
Rowid 字段类型: Rowid 是一行数据的一个唯一标识. ROWID 是数据的详细地址,通过 rowid,oracle 可以快速的定位某行具体的数据的位置. ROWID 可以分为物理 rowid ...
- hello1的web.xml解析
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" ...
- redis配置文档细节问题
在window10环境下,redis的.conf配置文件在使用时,不可以有多余的空白符.比如为了对其在配置的前方添加两个空格. 这么做会导致redis-server使用这个配置文件的时候无法正常启动, ...