zoukankan      html  css  js  c++  java
  • hdu 3879 Base Station

      1 做得还算麻利~
      2 /*最大闭合子图
      3 题意:建通讯站。每个通讯站有一定耗费,两个特定的通讯站之间建立通讯以后
      4 会有一定收益,问怎样建立通讯站可以使得收益最大 。
      5 ——最大权闭合子图->最小割
      6 ——url:http://acm.hdu.edu.cn/showproblem.php?pid=3879
      7 思路:
      8 首先考虑将图转化。
      9 即一条通讯线路有一定收益wi(即为正点权),但需要建立两个通讯站,
     10 这两个通讯站有一定造价pi(即为负点权)。
     11 将通讯线路也变成点,点权为收益,连两条有向只向两个通讯站。
     12 原来的通讯站点权不变。则start=0;end=m+n+1;totals=end+1;
     13 由此,题目转化为在新的图中求一个闭合图,使得其点权最大,即最大权闭合子图
     14 具体见图如下:
     15 建一个源点Start,与每个通讯线路的点相连,边权为收益
     16 建一个汇点end,end与每个通讯站相连,边权为建造费用
     17 通讯站与通讯线路之间的边权为无穷大
     18 最后的结果为所有通讯线路总的收益-最小割(最大流)
     19 */ 
     20 #include <iostream>
     21 #include<cstdio>
     22 #include<cstring>
     23 #include<vector>
     24 #include<queue>
     25 #include<algorithm>
     26 using namespace std;
     27 #define min(a,b) ((a)<(b))?(a):(b)
     28 #define max(a,b) ((a)>(b))?(a):(b)
     29 #define MAXN  60000//这里取略大于m+n+2的值(500+50000+2)所以这里取60000否则会runtime error 
     30 #define MAXM 5400000//M取N的平方倍或者N*9
     31 #define INF 0x3f3f3f3f
     32 
     33 struct node
     34 {
     35     int n;//点编号
     36     int w;//点权
     37 }Node[MAXN];
     38 //链式前向星
     39 struct enode
     40 {
     41     int t;
     42     int w;                //权值
     43     int c;                //流量
     44 //  int cost;
     45 //    int pre;            //前向指针
     46     int next;
     47 };
     48 
     49 
     50     struct enode e[MAXM];
     51     int box[MAXN],ecnt;
     52     //int etail[MAXN];        //尾部
     53     void init()
     54     {
     55         ecnt=0;
     56         memset(box,-1,sizeof(box));
     57     //    memset(etail,-1,sizeof(etail));        //初始化尾部
     58     }
     59     void addedge(int f,int t,int c)            //流量重载
     60     {
     61         e[ecnt].next=box[f];
     62         e[ecnt].t=t;
     63         e[ecnt].c=c;
     64         box[f]=ecnt++;
     65         e[ecnt].next=box[t];
     66         e[ecnt].t=f;
     67         e[ecnt].c=0;
     68         box[t]=ecnt++;
     69     }
     70 int sap(int s,int t,int N)//最大流问题
     71 {
     72     int gap[MAXN],lvl[MAXN],cur[MAXN],pre[MAXN];
     73     int curflow,ans=0,u,tmp,neck,i;
     74     memset(lvl,0,sizeof(lvl));
     75     memset(gap,0,sizeof(gap));
     76     memset(pre,-1,sizeof(pre));
     77     for(i=0;i<N;i++)
     78         cur[i]=box[i];
     79     gap[0]=N;
     80     u=s;
     81     while(lvl[s]<N)
     82     {
     83         if(u==t)
     84         {
     85             curflow=INF;
     86             for(i=s;i!=t;i=e[cur[i]].t)
     87             {
     88                 if(curflow>e[cur[i]].c)
     89                 {
     90                     neck=i;
     91                     curflow=e[cur[i]].c;
     92                 }
     93             }
     94             for(i=s;i!=t;i=e[cur[i]].t)
     95             {
     96                 tmp=cur[i];
     97                 e[tmp].c-=curflow;
     98                 e[tmp^1].c+=curflow;
     99             }
    100             ans+=curflow;
    101             u=neck;
    102         }
    103         for(i=cur[u];i!=-1;i=e[i].next)
    104             if(e[i].c && lvl[u]==lvl[e[i].t]+1)
    105                 break;
    106         if(i!=-1)
    107         {
    108             cur[u]=i;
    109             pre[e[i].t]=u;
    110             u=e[i].t;
    111         }
    112         else
    113         {
    114             if(--gap[lvl[u]]==0)
    115                 break;
    116              cur[u]=box[u];
    117             for(tmp=N,i=box[u];i!=-1;i=e[i].next)
    118                 if(e[i].c)
    119                     tmp=min(tmp,lvl[e[i].t]);
    120             lvl[u]=tmp+1;
    121             gap[lvl[u]]++;
    122             if(u!=s)
    123                 u=pre[u];
    124         }
    125     }
    126     return ans;
    127 }
    128 int main()
    129 {
    130      int m,n,a,b,c,t,w;
    131      int i,j,k;
    132      int start,end,ans;
    133   while(scanf("%d%d",&n,&m)!=EOF)  //;
    134    {
    135         //scanf("%d%d",&n,&m);
    136         start=ans=0;
    137         end=n+m+1;
    138         init();
    139         for(i=1;i<=n;i++)
    140         {
    141             scanf("%d",&w);
    142             addedge(i+m,end,w);//终点和负点权边相连
    143 
    144         }
    145         for(i=1;i<=m;i++)
    146         {
    147             scanf("%d%d%d",&a,&b,&c);//正点权
    148             ans+=c;
    149             addedge(i,b+m,INF);//建图关键
    150             addedge(i,a+m,INF);//建图关键
    151             addedge(start,i,c);
    152         }
    153         t=sap( start,end,end+1);//*/
    154         printf("%d\n",ans-t);
    155    }
    156     return 0;
    157 }
    158 /*
    159 Sample Input
    160 
    161 5 5
    162 1 2 3 4 5
    163 1 2 3
    164 2 3 4
    165 1 3 3
    166 1 4 2
    167 4 5 3
    168 
    169 Sample Output
    170 
    171 2
    172 */
  • 相关阅读:
    Clean Code读书笔记
    Junit 断言 assertThat Hamcrest匹配器
    SpringMVC 常用注解
    SpringMVC 流程 配置 接口
    ng-select ng-options ng-repeat的用法与区别
    javascript总结
    intellij安装 配置 创建项目
    git常用操作指令
    springmvc报错 org.springframework.web.servlet.DispatcherServlet
    linux笔记:RPM软件包管理-源码包管理
  • 原文地址:https://www.cnblogs.com/someonelikeyou/p/3036644.html
Copyright © 2011-2022 走看看