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 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 ≤ ij ≤ 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\n",ans2-1,ans1);
141     return 0;
142 }
View Code

 

 

posted @ 2019-01-21 23:00  断腿三郎  阅读(167)  评论(0编辑  收藏  举报