1. 程式人生 > >POJ 2987 Firing (最大權閉合圖)

POJ 2987 Firing (最大權閉合圖)

quest arch urn exp separate bsp -c algo logs

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 ≤ in). The remaining m lines each contain two integers i and j (1 ≤ i

, jn) 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

 

POJ 2987 Firing (最大權閉合圖)