• hdu 3879 Base Station (最大权 闭合图)


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

    好纠结的一道题啊 ,竟然 卡网络流的算法  。。。。。。用  dinic  tle   。。。。改为  isap  过了。。。。。。。

    题意:

    有n<= 5000个点可以用来建Station,题目给出了m个xi yi ci表示建立xi和yi个站点公司将获利ci,修建每个站点还需要成本, 让你求如何修建站点能使公司的收益最大?

    题解:

       找出依赖关系  要获得利益 ci  则  要 有建立  站 a  和 站 b  所以   添加一个  点  c   权值 为正   ,要修的 站 权值  为 负  连接  c->a  .c->b ;

      然后 求 最大权闭合图 即可!!

      1 #include<cstdio>
      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 inf 0x7fffffff
     12  #define maxn 60000
     13  #define CL(a,b) memset(a,b,sizeof(a))
     14 
     15  using namespace std;
     16  struct node
     17  {
     18      int to;
     19      int cap;
     20      int  next;
     21  }p[maxn*10] ;
     22  int dis[maxn],gap[maxn] ,cnt,next[maxn],s,e;// dis[i]为 到达 原点的层数
     23  int  n , m,NN ;//NN 为  加完点 之后的 总结点数
     24  void add(int from,int to,int cap)//加 的 是 有向边
     25  {
     26      p[cnt].to = to;
     27      p[cnt].cap = cap ;
     28      p[cnt].next = next[from];
     29      next[from] = cnt++;
     30 
     31      p[cnt].to = from;
     32      p[cnt].cap = 0;
     33      p[cnt].next = next[to];
     34      next[to] = cnt++ ;
     35  }
     36  int dfs(int pos,int cost)
     37  {
     38 
     39      if(pos == e)
     40       return cost ;
     41 
     42      int i,j ,mdis = NN ,f = cost ;
     43 
     44      for(i =  next[pos];i != - 1; i = p[i].next)
     45      {
     46          int to = p[i].to ;
     47          int cap = p[i].cap ;
     48          if(cap > 0 )
     49          {
     50              if(dis[to] + 1 == dis[pos])
     51              {
     52 
     53 
     54                int d = min(f,cap) ;// 注意 这 为 剩余 流量 和 cap 的 最小值
     55 
     56                d = dfs(to,d) ;
     57                p[i].cap -=d;
     58                p[i^1].cap +=d;
     59                f -= d;
     60 
     61                if(dis[s] >= NN)  return cost - f;// 如果没有 了 增广路经 结束算法
     62                if(f == 0break ;
     63              }
     64              if( dis[to] < mdis ) mdis = dis[to] ;// 记录可扩展的最小的狐
     65 
     66          }
     67 
     68      }
     69      if(f == cost)//  没有 可以 扩展的点
     70      {
     71          --gap[dis[pos]];
     72          if(gap[dis[pos]] == 0)dis[s] = NN;// 注意这 ,若 距离 为 dis[pos] 这一层都没有 扩展点了(断层) dis[s] = n
     73 
     74          dis[pos] = mdis + 1;//维护距离标号的方法是这样的:当找增广路过程中发现某点出发没有允许弧时,将这个点的距离标号设为由它出发的所有弧的终点的距离标号的最                                     小值加一
     75 
     76          ++gap[dis[pos]] ;
     77      }
     78      return cost  - f ;
     79  }
     80  int isap( int b,int t)
     81  {
     82 
     83      int ret =  0;
     84      s = b;
     85      e = t;
     86      CL(gap,0);
     87      CL(dis,0) ;
     88      gap[s] = NN ;//NN 为  加完点 之后的 总结点数
     89      while(dis[s] < NN)
     90      {
     91          ret+=dfs(s,inf) ;
     92      }
     93      return ret ;
     94 
     95  }
     96  int a[maxn] ;
     97 int main()
     98 {
     99     //read() ;
    100     int i, x,y;
    101     int d ;
    102      while(scanf("%d%d",&n,&m)!=EOF)
    103      {
    104          int sum  = 0 ;
    105 
    106          CL(next, -1);
    107 
    108 
    109          cnt = 0  ;
    110          int b = 0 ;
    111          int t = n + m + 1 ;
    112          NN  = n + m + 2;
    113          for(i = 1; i <= n;i++)
    114          {
    115              scanf("%d",&a[i]) ;
    116              add(i,t,a[i]) ;
    117          }
    118 
    119 
    120          for(i = 1 ; i <= m;i++)
    121          {
    122              scanf("%d%d%d",&x,&y,&d);
    123 
    124              add(b,n+i,d) ;
    125 
    126              sum += d ;
    127 
    128              add(n + i,x,inf) ;
    129 
    130 
    131              add(n + i ,y,inf) ;
    132 
    133 
    134 
    135 
    136          }
    137 
    138          int ans  = isap(b,t) ;
    139 
    140 
    141          //printf("%I64d   %I64d  +++++\n",sum , ans) ;
    142          printf("%d\n",sum - ans) ;
    143      }
    144 }
     
  • 相关阅读:
    从太空到地球某个位置的轨迹录像制作 | Earth Zoom in/out Tutorial (Record Video)
    DNA replication timing数据库
    探索ENCODE数据库 | Encyclopedia of DNA Elements
    第100天: 三木板模型算法项目实战
    第99天:UDP 编程
    第98天:图像库 PIL 实例—验证码去噪
    第97天:图像库 PIL(二)
    第96天:图像库 PIL(一)
    第95天:StringIO & BytesIO
    第94天:数据分析之 pandas 初步
  • 原文地址:https://www.cnblogs.com/acSzz/p/2764194.html
Copyright © 2020-2023  润新知