zoukankan      html  css  js  c++  java
  • 【POJ 2987 Firing】 最大权闭合子图

    题目链接:http://poj.org/problem?id=2987

    题目大意:一个公司有n个员工(里面包括董事长,经理,普通员工等等),现在遇见了金融危机,公司要开始裁员了,每个人对公司的价值不一样(可能为正可能为负),当你裁员一个员工时,这个员工他手下的员工必须一起裁掉,问你如何裁员能使公司得到的利益最大,而这种裁员方法必须得裁掉多少个员工。

    建图模型:最大权闭合子图指选择u,则u以下关系的都要选,一定要选到底,不能跳过u选它以下的。增设一个超级源点和一个超级汇点,(1->n)的点中,当点权为正时,从源点向该点连一条权值为点权大小的边,当点权为负时,从该点连一条权值大小为它的绝对值的边连向汇点。这种问题一般都是对于(u,v),如果选择u必须选择v,对(u,v)连一条容量为oo的边。

    裁员数等于靠近源点最小割一边的点数,最大利益=所有点正权值之和-最小割。

    View Code
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 const int mn=5555;
      9 const int mm=222222;
     10 const int oo=1e9;
     11 int node, st, sd, edge;
     12 int ver[mm], flow[mm], next[mm];
     13 int head[mn], work[mn], dis[mn], q[mn], visit[mn];
     14 
     15 inline void init(int _node, int _st, int _sd)
     16 {
     17     node=_node, st=_st, sd=_sd;
     18     for(int i=0; i<node; i++)
     19         head[i]=-1;
     20     edge=0;
     21 }
     22 
     23 void addedge(int u, int v, int c1, int c2)
     24 {
     25     ver[edge]=v, flow[edge]=c1, next[edge]=head[u],head[u]=edge++;
     26     ver[edge]=u, flow[edge]=c2, next[edge]=head[v],head[v]=edge++;
     27 }
     28 bool Dinic_bfs()
     29 {
     30     int i,u,v,l,r=0;
     31     for(i=0; i<node; ++i)dis[i]=-1;
     32     dis[q[r++]=st]=0;
     33     for(l=0; l<r; ++l)
     34         for(i=head[u=q[l]]; i>=0; i=next[i])
     35             if(flow[i]&&dis[v=ver[i]]<0)
     36             {
     37                 dis[q[r++]=v]=dis[u]+1;
     38                 if(v==sd)return 1;
     39             }
     40     return 0;
     41 }
     42 long long Dinic_dfs(int u, int exp)
     43 {
     44     if(u==sd) return exp;
     45     for(int &i=work[u]; i>=0; i=next[i])
     46     {
     47         int v=ver[i], tp;
     48         if(flow[i]&&dis[v]==dis[u]+1&&(tp=Dinic_dfs(v,min(flow[i],exp)))>0)
     49         {
     50             flow[i]-=tp;
     51             flow[i^1]+=tp;
     52             return tp;
     53         }
     54     }
     55     return 0;
     56 }
     57 long long Dinic_flow()
     58 {
     59     int i,delta;
     60     long long ret=0;
     61     while(Dinic_bfs())
     62     {
     63         for(i=0; i<node; ++i)work[i]=head[i];
     64         while(delta=Dinic_dfs(st,oo))ret+=delta;
     65     }
     66     return ret;
     67 }
     68 
     69 void DFS(int u)
     70 {
     71     visit[u]=1;
     72     for(int i=head[u], v; i>=0; i=next[i])
     73         if(flow[i]>0&&!visit[v=ver[i]]) DFS(v);
     74 }
     75 
     76 int main()
     77 {
     78     int n, m, w, u, v;
     79     while(~scanf("%d%d",&n,&m))
     80     {
     81         init(n+2,0,n+1);
     82         long long sum=0;
     83         for(int i=1; i<=n; i++)
     84         {
     85             scanf("%d",&w);
     86             if(w>0) sum+=w,addedge(st,i,w,0);
     87             if(w<0)  addedge(i,sd,-w,0);;
     88         }
     89         while(m--)
     90         {
     91             scanf("%d%d",&u,&v);
     92             addedge(u,v,oo,0);
     93         }
     94         long long maxflow=Dinic_flow();
     95         memset(visit,0,sizeof(visit));
     96         DFS(st);
     97         int ans=0;
     98         for(int i=1; i<=n; i++) ans+=visit[i];
     99         printf("%d %I64d\n",ans,sum-maxflow);
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    增加网站内容步骤
    简单使用
    dedecms的讲解 要求
    shop34-3-自动加载实现
    shop34-2-运转-平台分发
    shop34-1-目录布局
    match_controller
    match_model
    match_mvc
    laravel 路由
  • 原文地址:https://www.cnblogs.com/kane0526/p/3001557.html
Copyright © 2011-2022 走看看