zoukankan      html  css  js  c++  java
  • 【最大权闭合子图】BZOJ1497[NOI2006]-最大获利

    【题目大意】

    建立第i个通讯中转站需要的成本为Pi(1≤i≤N)。另外公司调查得出了所有期望中的用户群,一共M个。关于第i个用户群的信息概括为Ai, Bi和Ci:这些用户会使用中转站Ai和中转站Bi进行通讯,公司可以获益Ci。(1≤i≤M, 1≤Ai, Bi≤N) THU集团的CS&T公司可以有选择的建立一些中转站(投入成本),为一些用户提供服务并获得收益(获益之和)。那么如何选择最终建立的中转站才能让公司的净获利最大呢?(净获利 = 获益之和 - 投入成本之和)

    【思路】

    根据最大权闭合子图的结论进行建图,超级源点和中转站相连,容量为成本;A与B中转站分别连向某个用户,容量为INF;再由某个用户连向超级汇点,容量为收益值。

    最终答案=∑(所有用户群的总收益)-最大流。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<cstdlib>
      7 #include<vector>
      8 #include<cmath>
      9 #include<queue>
     10 #define target m+n+1 
     11 using namespace std;
     12 const int MAXN=600000;
     13 const int INF=0x7fffffff;
     14 struct node 
     15 {
     16     int to,pos,cap;
     17 };
     18 vector<node> E[MAXN];
     19 int n,m;
     20 int sum=0;
    22 int dist[MAXN];
     23 
     24 void addedge(int u,int v,int w) 
     25 {
     26     E[u].push_back((node){v,E[v].size(),w});
     27     E[v].push_back((node){u,E[u].size()-1,0});
     28 }
     29 
     30 void init()
     31 {    
     32     scanf("%d%d",&n,&m);
     33     for (int i=1;i<=n;i++)
     34     {
     35         int p;
     36         scanf("%d",&p);
     37         addedge(0,i,p);
     38     }
     39     for (int i=1;i<=m;i++)
     40     {
     41         int a,b,c;
     42         scanf("%d%d%d",&a,&b,&c);
     43         addedge(a,i+n,INF);
     44         addedge(b,i+n,INF);
     45         addedge(i+n,target,c);
     46         sum+=c;
     47     }
     48 }
     49 
     50 int bfs() 
     51 {
     52     memset(dist,-1,sizeof(dist));
     53     queue<int> que;
     54     while (!que.empty()) que.pop();
     55     que.push(0);
     56     dist[0]=0;
     57     
     58     while (!que.empty()) 
     59     {
     60         int head=que.front();
     61         que.pop();
     62         for (int i=0; i<E[head].size(); i++) 
     63         {
     64             node &tmp=E[head][i];
     65             if (dist[tmp.to]==-1 && tmp.cap>0)
     66             {    
     67                 dist[tmp.to]=dist[head]+1;
     68                 que.push(tmp.to);
     69                 if (tmp.to==target) return 1;
     70             }
     71         }
     72     }
     73     return 0;
     74 }
     75 
     76 
     77 int dfs(int s,int e,int f) 
     78 {
     79     int ret=0;
     80     if (s==e || f==0) return(f);
     81     for (int i=0; i<E[s].size(); i++)//此处可添加当前弧优化,但是效率反而会低orz 
     82     {
     83         node  &tmp=E[s][i];
     84         if (dist[tmp.to]==dist[s]+1 && tmp.cap>0) 
     85         {
     86             int delta=dfs(tmp.to,e,min(tmp.cap,f));
     87             if (delta>0) 
     88             {
     89                 ret+=delta;
     90                 tmp.cap-=delta;
     91                 E[tmp.to][tmp.pos].cap+=delta;
     92                 f-=delta;//不要忘记f要减去delta! 没有加的时候是60s,加了ret累加后瞬间快了 
     93             }
     94         }
     95     }
     96     return ret;
     97 }
     98 
     99 void dinic()
    100 {
    101     int flow=0;
    102     while (bfs()) 
    103     {
    104         for (;;) 
    105         {
    106             int f=dfs(0,target,INF);
    108             if (f==0) break;
    109             else flow+=f;
    110         }
    111     }
    112     int ans=sum-flow;
    113     cout<<ans<<endl;
    114 }
    115 
    116 int main()
    117 {
    118     init();
    119     dinic();
    120     return 0;
    121 }
  • 相关阅读:
    合理处理沉没成本
    推荐一个基于Ajax的查询API网站
    为blog添加天气预报功能
    我仅仅一个熟练的coder
    管理和IT的对话
    10个你未必知道的CSS技巧
    如何使用ajax开发web应用程序(二)
    5月20日,系分考试后感。
    说说大型高并发高负载网站的系统架构
    盗用sina的爱问投诉代码实现网页对话框。
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5246582.html
Copyright © 2011-2022 走看看