POJ 2987 Firing 网络流 最大权闭合图

http://poj.org/problem?id=2987

https://blog.csdn.net/u014686462/article/details/48533253

给一个闭合图,要求输出其最大权闭合图的权值和需要选的最少点数,最大权闭合图定义和网络流连边方式见博客。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<queue>
 7 using namespace std;
 8 #define LL long long
 9 const int maxn=10010;
10 const LL minf=(LL)1e14;
11 int n,m,s,t;
12 LL val[maxn]={};
13 struct nod{
14     int y,next;LL v;
15 }e[maxn*20];
16 int head[maxn],tot=1;
17 queue<int>q;
18 int dep[maxn]={},vis[maxn]={},id[maxn]={},tai=0;
19 void init(int x,int y,LL v){
20     e[++tot].y=y;e[tot].v=v;e[tot].next=head[x];head[x]=tot;
21 }
22 bool dfs(){
23     memset(dep,0,sizeof(dep));
24     q.push(s);dep[s]=1;
25     while(!q.empty()){
26         int x=q.front();q.pop();
27         for(int i=head[x];i;i=e[i].next){
28             if(e[i].v&&!dep[e[i].y]){
29                 dep[e[i].y]=dep[x]+1;
30                 q.push(e[i].y);
31             }
32         }
33     }
34     return dep[t];
35 }
36 LL dfs1(int x,LL fc){
37     if(x==t){
38         return fc;
39     }
40     LL he=0,z;
41     for(int i=head[x];i;i=e[i].next){
42         if(dep[x]+1==dep[e[i].y]){
43             z=dfs1(e[i].y,min(fc-he,e[i].v));
44             he+=z;e[i].v-=z;e[i^1].v+=z;
45             if(he==fc)break;
46         }
47     }
48     return he;
49 }
50 void dfs2(int x){
51     if(x==t)return;
52     if(x!=s)id[++tai]=x;
53     vis[x]=1;
54     for(int i=head[x];i;i=e[i].next){
55         if(e[i].v&&!vis[e[i].y]){
56             dfs2(e[i].y);
57         }
58     }
59 }
60 int main(){
61     int x,y; LL ans=0;
62     scanf("%d%d",&n,&m);
63     s=n+1;t=s+1;
64     for(int i=1;i<=n;i++){
65         scanf("%lld",&val[i]);
66         if(val[i]>=0){init(s,i,val[i]);init(i,s,0);ans=ans+val[i];}
67         else {init(i,t,-val[i]);init(t,i,0);}
68     }
69     for(int i=1;i<=m;i++){
70         scanf("%d%d",&x,&y);
71         init(x,y,minf);init(y,x,0);
72     }
73     while(dfs())ans-=dfs1(s,minf);
74     dfs2(s);
75     printf("%d ",tai);
76     printf("%lld\n",ans);
77     return 0;
78 }

原文地址:https://www.cnblogs.com/137shoebills/p/9100790.html

时间: 2024-11-06 17:54:50

POJ 2987 Firing 网络流 最大权闭合图的相关文章

poj - 2987 - Firing(最大权闭合图)

题意:n(0 < n ≤ 5000)个人,m(0 ≤ m ≤ 60000)个上下级关系,炒一个人可以获得收益或者损失bi (|bi| ≤ 10 ^ 7, 1 ≤ i ≤ n),炒一个人会把他的所有下级一起炒掉,问怎样炒人使收益最大,输出最大收益和最少炒人的数量. 题目链接:http://poj.org/problem?id=2987 -->>炒一个人会把他的所有下级一起炒掉,这时存在依赖关系,对应图论中的闭合图..最大收益对应最大权和..于是,最大权闭合图上场.. 最少炒人数?获得最大收

POJ 2987 Firing (最大权闭合图)

Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12108   Accepted: 3666 Description You've finally got mad at "the world's most stupid" employees of yours and decided to do some firings. You're now simply too mad to give resp

POJ 2987 Firing(最大权闭合)

POJ 2987 Firing 题目链接 题意:n个人,每个人被炒由于都会得到一个利益(可正可负),现在有一些下属关系,如果一个人被炒了,他的下属要一起炒掉,问怎么炒使得炒利益最大,炒的人最少 思路:最大权闭合的题,要处理最少,那么其实就是在求最小割分成两个集合的时候,尽量让点都到T集合去,那么只要从S进行一次dfs,遇到满流的边就停止,经过的点都给S,就是要炒掉的人了 代码: #include <cstdio> #include <cstring> #include <qu

poj 2987 Firing【最大权闭合子图+玄学计数 || BFS】

玄学计数 LYY Orz 第一次见这种神奇的计数方式,乍一看非常不靠谱但是仔细想想还卡不掉 就是把在建图的时候把正权变成w*10000-1,负权变成w*10000+1,跑最大权闭合子图.后面的1作用是计数,因为在最大权闭合子图中划到s点一侧的代表选,这样一来,后四位就是起了计数作用.sum初始统计的个数就是所有正权点,然后dinic中割掉一个正权点的边即相当于在最终答案的后四位+1,也就是点数-1 然后考虑收益相同的方案,点数多的后四位一定小,而当前求得又是最小割,所以会选割掉点数少的,也就是留

BZOJ 1497 JZYZOJ 1344 [NOI2006]最大获利 网络流 最大权闭合图

http://www.lydsy.com/JudgeOnline/problem.php?id=1497 http://172.20.6.3/Problem_Show.asp?id=1344 思路:(最大权闭合图的思路相同) 将所有的用户群获利(正值)作为一个点连一条权值为获利值的边到st点,将所有的建站消耗(输入的是正值但是是在获利中减去的所以实质还是负值)作为一个点连一条权值为消耗值的边到ed点,再将每个用户群点和其依赖的建站点连一条权值为无穷的边,求st到ed的最大流. 此时,所求的最大获

【暖*墟】#网络流# 最大权闭合子图

[相关概念详解] 闭合图:有向图的一个点集,且这个点集的所有出边仍然指向该点集. 最大权闭合图:(每一个点有一个权值)在所有的合法闭合图中,点权之和最大的图. 处理问题:权值有正有负,重复选只算一次,选择有相互关联性 的问题. 首先有一个有向连通图(闭合图),每个点带有一个权值,例如: 造出一个超级源点S和一个超级汇点T,把S连边到所有带有正权的点上,每条边的容量是这个点的权: 把所有带负权的点连边到T,每条边的容量是这个点的权的相反数(正值).原来的边的容量设成无限大. 所有的点按权值的正负连

【bzoj3996】[TJOI2015]线性代数 最大权闭合图

题目描述 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大.其中A^T为A的转置.输出D 输入 第一行输入一个整数N,接下来N行输入B矩阵,第i行第J个数字代表Bij. 接下来一行输入N个整数,代表矩阵C.矩阵B和矩阵C中每个数字都是不超过1000的非负整数. 输出 输出最大的D 样例输入 3 1 2 1 3 1 0 1 2 3 2 3 7 样例输出 2 题解 网络流最大权闭合图 (推导过程什么的不重要,只要注意一下矩阵乘法不满足结合律

POJ 2987 Firing (最大权闭合图,最小割)

http://poj.org/problem?id=2987 Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7865   Accepted: 2377 Description You've finally got mad at "the world's most stupid" employees of yours and decided to do some firings. You're n

POJ 2987 Firing 最大权闭合图

点击打开链接 Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7976   Accepted: 2409 Description You've finally got mad at "the world's most stupid" employees of yours and decided to do some firings. You're now simply too mad to giv