• HDU 3879 Base Station


    题意:有n个城市。现在需要在这些城市上修一些通信的基站,在每个城市上修一个基站都需要花费一定的费用。另外给出m个组合(a,b,c),表示如果第a个城市和第b个城市都修起了基站,那么公司可以获利c。但公司并不需要在每个城市都修基站,他们只希望自己能够获得最大的利益。问最大利益。

    裸的最大闭合子图吧。只要知道这个模型就是水题。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #include <algorithm>
     5 #define INF 1<<30
     6 #define maxn 55010
     7 #define maxm 400000
     8 using namespace std;
     9 int v[maxm],next[maxm],w[maxm];
    10 int first[maxn],d[maxn],q[maxn],work[maxn];
    11 int e,S,T;
    12 
    13 void init(){
    14     e = 0;
    15     memset(first,-1,sizeof(first));
    16 }
    17 
    18 
    19 void add_edge(int a,int b,int c){
    20     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
    21     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
    22 }
    23 
    24 int bfs(){
    25     int rear = 0;
    26     memset(d,-1,sizeof(d));
    27     d[S] = 0;q[rear++] = S;
    28     for(int i = 0;i < rear;i++){
    29         for(int j = first[q[i]];j != -1;j = next[j])
    30             if(w[j] && d[v[j]] == -1){
    31                 d[v[j]] = d[q[i]] + 1;
    32                 q[rear++] = v[j];
    33                 if(v[j] == T)   return 1;
    34             }
    35     }
    36     return 0;
    37 }
    38 
    39 int dfs(int cur,int a){
    40     if(cur == T)    return a;
    41     for(int &i = work[cur];i != -1;i = next[i]){
    42         if(w[i] && d[v[i]] == d[cur] + 1)
    43             if(int t = dfs(v[i],min(a,w[i]))){
    44                 w[i] -= t;w[i^1] += t;
    45                 return t;
    46             }
    47     }
    48     return 0;
    49 }
    50 
    51 int dinic(){
    52     int ans = 0;
    53     while(bfs()){
    54         memcpy(work,first,sizeof(first));
    55         while(int t = dfs(S,INF))   ans += t;
    56     }
    57     return ans;
    58 }
    59 
    60 
    61 int main(){
    62     int n,m;
    63     while(scanf("%d%d",&n,&m) == 2){
    64         init();
    65         S = 0,T = n+m+1;
    66         int sum = 0;
    67         for(int i = 1;i <= n;i++){
    68             int tmp;
    69             scanf("%d",&tmp);
    70             add_edge(i,T,tmp);
    71         }
    72         for(int i = 1;i <= m;i++){
    73             int a,b,c;
    74             scanf("%d%d%d",&a,&b,&c);
    75             sum += c;
    76             add_edge(S,i+n,c);
    77             add_edge(i+n,a,INF);
    78             add_edge(i+n,b,INF);
    79         }
    80         printf("%d
    ",sum - dinic());
    81     }
    82 }
    View Code
  • 相关阅读:
    windows2008R2新增磁盘处于脱机状态及介质写入受保护解决办法
    Oracle查询字段结果加单引号以及其他内容
    系统部署Oracle及cmd命令
    如何允许谷歌浏览器Adobe Flash Player一直运行
    浏览器被hao123篡改怎么办?
    Oracle数据库备份还原
    11_程序中的循环
    10_选择结构
    09_控制台输入
    08_运算符
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3402930.html
Copyright © 2020-2023  润新知