zoukankan      html  css  js  c++  java
  • hdu 3996 Gold Mine ( 最大权闭合图 )

    http://acm.hdu.edu.cn/showproblem.php?pid=3996

    题意 :  

    1. 题意: 有 n 个金矿,每个金矿开发需要一定的价值,开发之后可以获得一定的价值,而且一些金矿受到另一些金矿的限制,即开采这个金矿之前要开采 
    2.            限制它的金矿,问最多可以获得多少价值。

    题解:

          很明显的 最大权闭合图    金矿 ,有  开采的 花费 和价值 ,那么  开采的 利益就 是   价值 - 花费  ;

        

    1. 如果某个金矿的开发利润为正值,就在源点和该点之间连一条容量为该利润的边 
    2.           如果某个金矿的开发利润为负值,就在该点和汇点之间连一条容量为该利润绝对值的边 
    3.           如果某个金矿收到另一个金矿的限制,就在两个金矿之间连一条容量为INF的边。 
    4.           累计所有正值利润的和  sum,获得的最大利润为sum - maxflow


      1  #include<stdio.h>
      2  #include<cstring>
      3  #include<cmath>
      4  #include<iostream>
      5  #include<algorithm>
      6  #include<set>
      7  #include<map>
      8  #include<queue>
      9  #include<vector>
     10  #include<string>
     11  #define Min(a,b) a<b?a:b
     12  #define Max(a,b) a>b?a:b
     13  #define CL(a,num) memset(a,num,sizeof(a));
     14  #define maxn  5100
     15  #define eps  1e-6
     16  #define inf  10000000000
     17  #define read() freopen("data.in","r",stdin) ;
     18  #define ll __int64
     19  using namespace std;
     20  ll n , m ;
     21  struct node
     22  {
     23      int from;
     24      int to ;
     25      ll flow ;
     26      int next ;
     27  } p[maxn*100];
     28  int  head[maxn] ,s,t,cnt,dis[maxn];
     29  ll a[maxn]  ,ans,num,sum;
     30 
     31  bool vis[maxn] ;
     32 
     33  queue<int>que ;
     34  void add(int from ,int to , ll flow )
     35  {
     36      p[cnt].to = to ;
     37      p[cnt].flow =flow ;
     38      p[cnt].next = head[from] ;
     39      head[from] = cnt++ ;
     40 
     41      p[cnt].to = from ;
     42      p[cnt].flow = 0 ;
     43      p[cnt].next  = head[to] ;
     44      head[to] = cnt++ ;
     45 
     46  }
     47 
     48  int bfs()
     49  {
     50      CL(dis,-1)  ;
     51      dis[s] =  0 ;
     52      int i ;
     53      while(!que.empty())que.pop() ;
     54 
     55      que.push(s) ;
     56      while(!que.empty())
     57      {
     58          int u = que.front() ;que.pop() ;
     59 
     60          for(i = head[u] ; i != -1  ;i = p[i].next)
     61          {
     62                 int v = p[i].to ;
     63 
     64                 ll flow  = p[i].flow ;
     65 
     66                 if(flow > 0)
     67                 if(dis[v] < 0 )
     68                 {
     69                     dis[v] = dis[u] + 1 ;
     70                     que.push(v) ;
     71                 }
     72 
     73          }
     74 
     75      }
     76 
     77      if(dis[t] > 0return 1;
     78      else return 0 ;
     79 
     80 
     81 
     82  }
     83 
     84 
     85  ll dfs(int x,ll mx)
     86  {
     87 
     88 
     89      if(x == t) return mx ;
     90 
     91      int i ;
     92      ll a ,tf = 0;
     93 
     94 
     95       for(i = head[x] ; i != -1 ; i = p[i].next)
     96       {
     97           int v = p[i].to ;
     98           ll  flow  = p[i].flow ;
     99           if(flow > 0)
    100           {
    101                if( dis[v] == dis[x] + 1 && (a = dfs(v,min(flow ,mx))))
    102             {
    103                p[i].flow -= a ;
    104                p[i^1].flow += a;
    105 
    106              return a ;
    107             }
    108 
    109           }
    110 
    111       }
    112 
    113 
    114       if(!tf) dis[x] = - 1;
    115       return tf ;
    116 
    117  }
    118 
    119  ll dinic()
    120  {
    121 
    122      ans = 0 ;
    123      ll res = 0 ;
    124      while(bfs())
    125      {
    126          while(res = dfs(s,inf))ans += res ;
    127      }
    128 
    129      return  ans  ;
    130 
    131 
    132  }
    133 
    134 int main()
    135 {
    136     int T,i,j,a,b,num ;
    137     ll cost ,val;
    138     scanf("%d",&T);
    139     int cas = 0 ;
    140     ll  sum ;
    141     while(T--)
    142     {
    143 
    144         CL(head, -1) ;
    145         cnt = 0 ;
    146         sum = 0 ;
    147         scanf("%d",&n);
    148 
    149         s = 0 ;
    150         t = n*26 + n + 1 ;
    151 
    152         for(i = 1 ; i <= n;i++)
    153         {
    154             scanf("%d",&m);
    155             for(j = 1 ;  j <= m;j++)
    156             {
    157                 scanf("%I64d%I64d%d",&cost,&val,&num);
    158 
    159                 ll  tmp = val -  cost ;
    160                 if(tmp > 0)
    161                 {
    162                     add(s,i*26 + j,tmp);
    163 
    164                      sum += tmp ;
    165                 }
    166                 else
    167                 {
    168                      add(i*26 + j,t, -tmp) ;
    169 
    170                 }
    171 
    172 
    173                 while(num--)
    174                 {
    175                     scanf("%d%d",&a,&b);
    176                     add(i*26+j,a*26 + b,inf) ;
    177                 }
    178             }
    179         }
    180 
    181         ll ans = dinic() ;
    182 
    183         printf("Case #%d: %I64d\n",++cas,sum - ans) ;
    184 
    185     }
    186 }


  • 相关阅读:
    杭电2060WA
    杭电2060
    UVa10082 没有通过
    百度笔试题目02
    百度笔试题目01
    Q1002 四则运算
    百度笔试题目
    约瑟夫环 详细的分析
    算法导论03
    汉诺塔01
  • 原文地址:https://www.cnblogs.com/acSzz/p/2763896.html
Copyright © 2011-2022 走看看