POJ 2987 Firing (最大权闭合图)
Posted zgqblogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2987 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 response to questions like “Don’t you think it is an even more stupid decision to have signed them?”, yet calm enough to consider the potential profit and loss from firing a good portion of them. While getting rid of an employee will save your wage and bonus expenditure on him, termination of a contract before expiration costs you funds for compensation. If you fire an employee, you also fire all his underlings and the underlings of his underlings and those underlings’ underlings’ underlings… An employee may serve in several departments and his (direct or indirect) underlings in one department may be his boss in another department. Is your firing plan ready now?
Input
The input starts with two integers n (0 < n ≤ 5000) and m (0 ≤ m ≤ 60000) on the same line. Next follows n + m lines. The first n lines of these give the net profit/loss from firing the i-th employee individually bi (|bi| ≤ 107, 1 ≤ i ≤ n). The remaining m lines each contain two integers i and j (1 ≤ i, j ≤ n) meaning the i-th employee has the j-th employee as his direct underling.
Output
Output two integers separated by a single space: the minimum number of employees to fire to achieve the maximum profit, and the maximum profit.
Sample Input
5 5 8 -9 -20 12 -10 1 2 2 5 1 4 3 4 4 5
Sample Output
2 2
思路:
有一张图够了,来自:
https://www.cnblogs.com/kane0526/archive/2013/04/05/3001557.html
值得一提的是,我在DFS找点数的过程中,在残余网络中寻找时,限制了k(边下标)为偶数,以表示该边是原图中的边。(因为我的网络流奇数边是原图的反向边),但是WA,去掉这个限制就对了,目前不知道问题出在哪里。
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<stack> 5 #include<queue> 6 #include<map> 7 #include<set> 8 #include<cstdio> 9 #include<cstring> 10 #include<cmath> 11 #include<ctime> 12 #define fuck(x) cout<<#x<<" = "<<x<<endl; 13 #define ls (t<<1) 14 #define rs ((t<<1)+1) 15 using namespace std; 16 typedef long long ll; 17 typedef unsigned long long ull; 18 const int maxn = 300086; 19 const ll Inf = 999999999999999; 20 const int mod = 1000000007; 21 //const double eps = 1e-6; 22 //const double pi = acos(-1); 23 int n,m,s,t; 24 int Head[5510],v[maxn],Next[maxn],cnt; 25 ll w[maxn]; 26 void init(){ 27 s=0;t=n+2; 28 memset(Head,-1,sizeof(Head)); 29 cnt=0; 30 } 31 int vis[5510],num[5510]; 32 void add(int x,int y,ll z) 33 { 34 // cout<<x<<" "<<y<<" "<<z<<endl; 35 if(x==y){return;} 36 v[cnt]=y; 37 w[cnt]=z; 38 Next[cnt]=Head[x]; 39 Head[x]=cnt++; 40 41 v[cnt]=x; 42 w[cnt]=0; 43 Next[cnt]=Head[y]; 44 Head[y]=cnt++; 45 } 46 47 bool bfs() 48 { 49 memset(vis,0,sizeof(vis)); 50 for(int i=0;i<=t;i++){ 51 num[i]=Head[i]; 52 } 53 vis[s]=1; 54 queue<int>q; 55 q.push(s); 56 int r=0; 57 while(!q.empty()){ 58 int u=q.front(); 59 q.pop(); 60 int k=Head[u]; 61 while(k!=-1){ 62 if(!vis[v[k]]&&w[k]){ 63 vis[v[k]]=vis[u]+1; 64 q.push(v[k]); 65 } 66 k=Next[k]; 67 } 68 } 69 return vis[t]; 70 } 71 72 ll dfs(int u,ll f) 73 { 74 75 if(u==t){return f;} 76 int &k=num[u]; 77 while(k!=-1){ 78 if(vis[v[k]]==vis[u]+1&&w[k]){ 79 ll d=dfs(v[k],min(f,w[k])); 80 if(d>0){ 81 w[k]-=d; 82 w[k^1]+=d; 83 // fuck(d) 84 return d; 85 } 86 } 87 k=Next[k]; 88 } 89 return 0ll; 90 } 91 ll Dinic() 92 { 93 ll ans=0; 94 while(bfs()){ 95 ll f; 96 while((f=dfs(s,Inf))>0){ 97 ans+=f; 98 } 99 } 100 return ans; 101 } 102 103 int ans2=0; 104 105 void dfst(int x) 106 { 107 ans2++; 108 vis[x]=1; 109 for(int k=Head[x];k!=-1;k=Next[k]){ 110 if(w[k]&&!vis[v[k]]){dfst(v[k]);} 111 } 112 } 113 114 int main() 115 { 116 // ios::sync_with_stdio(false); 117 // freopen("in.txt","r",stdin); 118 119 scanf("%d%d",&n,&m); 120 init(); 121 ll all=0; 122 for(int i=1;i<=n;i++){ 123 ll x; 124 scanf("%lld",&x); 125 if(x>0){all+=x;add(s,i,x);} 126 else{ 127 add(i,t,-x); 128 } 129 } 130 for(int i=1;i<=m;i++){ 131 int x,y; 132 scanf("%d%d",&x,&y); 133 add(x,y,Inf); 134 } 135 ll ans1=all-Dinic(); 136 137 memset(vis,0,sizeof(vis)); 138 139 dfst(s); 140 printf("%d %lld ",ans2-1,ans1); 141 return 0; 142 }
以上是关于POJ 2987 Firing (最大权闭合图)的主要内容,如果未能解决你的问题,请参考以下文章