• 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
    ",ans2-1,ans1);
    141     return 0;
    142 }
    View Code
     
    
    
  • 相关阅读:
    C#CreateGraphics方法的三种实现方式
    二叉树的性质和常用操作代码集合
    《Java程序设计基础》 第8章手记Part 2
    《Java程序设计基础》 第8章手记Part 1
    STL 算法罗列 (转)
    STL 练习
    STL所有算法简介 (转) http://www.cnblogs.com/yuehui/archive/2012/06/19/2554300.html
    linux 解压命令
    杭电1016
    杭电1257
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/10301458.html
Copyright © 2020-2023  润新知