• BZOJ 1497 [NOI2006]最大获利 【最大流】


    Description

    新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战。THU集团旗下的CS&T通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就站址选择一项,就需要完成前期市场研究、站址勘测、最优化等项目。在前期市场调查和站址勘测之后,公司得到了一共N个可以作为通讯信号中转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第i个通讯中转站需要的成本为Pi(1≤i≤N)。另外公司调查得出了所有期望中的用户群,一共M个。关于第i个用户群的信息概括为Ai, Bi和Ci:这些用户会使用中转站Ai和中转站Bi进行通讯,公司可以获益Ci。(1≤i≤M, 1≤Ai, Bi≤N) THU集团的CS&T公司可以有选择的建立一些中转站(投入成本),为一些用户提供服务并获得收益(获益之和)。那么如何选择最终建立的中转站才能让公司的净获利最大呢?(净获利 = 获益之和 - 投入成本之和)

    Hint

    N≤5 000,M≤50 000,0≤Ci≤100,0≤Pi≤100

    Solution

    题意:有一些点,选择一个点需要一定代价,有一些边,如果边连接的两点都被选择了,获得一定价值,求价值最大

    其实是道非常典型的最小割模型

    将题意转换一下理解,假设我们已经获得了所有的边的价值,此时对于任意一条边,我们要么花费一定的代价去选择它所连的两点,要么舍弃这条边的价值

    两种方法都可以视作网络流中一条割边

    全局代价最小,就是求最小割,也就是最大流

    重新构图,跑最大流

    //感觉每次写网络流都算不清边数,无限RE= =

      1 #include<bits/stdc++.h>
      2 
      3 #define maxn 60000+5
      4 #define maxm 600000+5
      5 #define set(a,b) memset(a,(b),sizeof(a))
      6 #define fr(i,a,b) for(ll i=(a),_end_=(b);i<=_end_;i++)
      7 #define rf(i,b,a) for(ll i=(a),_end_=(b);i>=_end_;i--)
      8 #define fe(i,a,b) for(int i=first[(b)],_end_=(a);i!=_end_;i=s[i].next)
      9 #define fec(i,a,b) for(int &i=cur[(b)],_end_=(a);i!=_end_;i=s[i].next)
     10 
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 
     15 struct sides{
     16   int u,v,c;
     17   int next;
     18 }s[maxm];
     19 
     20 queue<int> q;
     21 int first[maxn],cur[maxn];
     22 int h[maxn],ind=0;
     23 int sum=0,cost=0;
     24 int n,m;
     25 
     26 void add(int u,int v,int c)
     27 {
     28   s[ind].u=u,s[ind].v=v,s[ind].c=c;
     29   s[ind].next=first[u],first[u]=ind;
     30   ind++;
     31   
     32   s[ind].u=v,s[ind].v=u,s[ind].c=0;
     33   s[ind].next=first[v],first[v]=ind;
     34   ind++;
     35 }
     36 
     37 bool bfs()
     38 {
     39   set(h,-1);
     40   h[0]=1;
     41   q.push(0);
     42   while( !q.empty() ){
     43     int sd=q.front();q.pop();
     44     fe(i,-1,sd)
     45       if( s[i].c && h[s[i].v]==-1 ){
     46     h[s[i].v]=h[sd]+1;
     47     q.push(s[i].v);
     48       }
     49   }
     50   return h[n+m+1]!=-1;
     51 }
     52 
     53 int dfs(int u,int flow)
     54 {
     55   if( u==n+m+1 ) return flow;
     56   int w,used=0;
     57   fec(i,-1,u)
     58     if( s[i].c && h[s[i].v]==h[u]+1 ){
     59       w=dfs(s[i].v,min(flow-used,s[i].c));
     60       s[i].c-=w,s[i^1].c+=w;
     61       used+=w;
     62       if( used==flow )
     63     return flow;
     64     }
     65   if( !used ) h[u]=-1;
     66   return used;
     67 }
     68 
     69 void dinic()
     70 {
     71   while( bfs() ){
     72     fr(i,0,n+m+1)
     73       cur[i]=first[i];
     74     cost+=dfs(0,INT_MAX);
     75   }
     76 }
     77 
     78 int main()
     79 {
     80 #ifndef ONLINE_JUDGE
     81   freopen("1497.in","r",stdin);
     82   freopen("1497.out","w",stdout);
     83 #endif
     84   set(first,-1);
     85   cin >> n >> m ;
     86   fr(i,1,n){
     87     int k;
     88     cin >> k ;
     89     add(0,i,k);
     90   }
     91   fr(i,1,m){
     92     int u,v,c;
     93     cin >> u >> v >> c ;
     94     add(u,n+i,INT_MAX);
     95     add(v,n+i,INT_MAX);
     96     add(n+i,n+m+1,c);
     97     sum+=c;
     98   }
     99   dinic();
    100   cout << sum-cost ;
    101   return 0;
    102 }
  • 相关阅读:
    jquery省市联动,根据公司需求而写
    jquery.easyui使用详解,和遇到的问题,提供大家在使用的时候少走弯路(二)
    div内容滚动,无缝滚动
    使用CSS修改HTML5 input placeholder颜色( 转载 )
    如何编写规范,灵活,稳定,高质量的HTML和css代码
    div+css实现未知宽高元素垂直水平居中
    原生JavaScript实现的addclass,removeclass,hasclass,toggleclass,getbyclass
    JS判断上传图片格式是否正确
    文字超出限制字数后隐藏
    JS判断输入框值是否为空
  • 原文地址:https://www.cnblogs.com/ST-Saint/p/4617646.html
Copyright © 2020-2023  润新知