【UVALive - 3487】 Duopoly(网络流-最小割)

Description

The mobile network market in country XYZ used to be dominated by two large corporations, XYZ
Telecom and XYZ Mobile. The central government recently has realized that radio frequency spectrum
is a scarce resource and wants to regulate its usage. The spectrum currently in use is divided into
300,000 channels. Any wireless service provider who wishes to use certain spectrum should apply for
licenses on these channels. While some services may require use of multiple channels, a single channel
can not be shared by different services.
The central government wants to maximize its revenue from the spectrum by putting the channels
up to an auction. The only two bidders are XYZ Telecom and XYZ Mobile. They are allowed to place
bids on combinations of channels, through which their services can communicate with the customers.
Furthermore, the government stipulates that a company can only place at most one bid on a specific
channel.
The government can only accept a subset of the bids so none of them would conflict with each
other. However, officials soon find out that it is a difficult task to determine the winning bids in order
to maximize the revenue, and they are asking for your help.

Input
Standard input will contain multiple test cases. The first line of the input is a single integer T (1 ≤
T ≤ 10) which is the number of test cases. T test cases follow, each preceded by a single blank line.
Each test case has two bid description sections, which are for XYZ Telecom and XYZ Mobile,
respectively. Each section starts with an integer N (1 ≤ N ≤ 3, 000), which is the number of bids that
follow. The next N lines each contain the description for one bid, the first integer P (1 ≤ P ≤ 1, 000)
gives the price of that bid, followed by the channel numbers required by this service. A service would
require at least 1 channel and at most 32 channels. Each channel number is a positive integer and will
never exceed 300,000.

Output
Results should be directed to standard output. Start each case with ‘Case #:’ on a single line, where
# is the case number starting from 1. Two consecutive cases should be separated by a single blank
line. No blank line should be produced after the last test case.
For each test case, print the maximized revenue the government is able to collect by issuing licenses
on the channels.

Sample Input

2
3
45 1
51 2
62 3
4
54 1
15 2
33 3
2 4 5
5
20 1
18 2
23 4
54 3 5 6
17 7
4
36 1 2 3
28 5
47 4 7
16 6

Sample Output
Case 1:
169
Case 2:
139

【题意】

  有两家公司都想向政府申请某些资源的使用权,并且他们都提供了一些申请列表,列表中含有申请费用和资源种类,同一家公司的申请列表之间不含有重复的资源。政府只可以完整地接受和拒绝谋一份申请列表,问政府的最大收益是多少。

【分析】

  对于一组,新建一个点连源点(或汇点),流量为费用,再连向组内的全部点(流量为INF),最后跑一遍最小割即可。

代码如下:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<queue>
  7 using namespace std;
  8 #define INF 0xfffffff
  9 #define Maxn 600010
 10
 11 int st,ed;
 12 struct node
 13 {
 14     int x,y,f,o,next;
 15 }t[Maxn*2];int len;
 16
 17 int first[Maxn],dis[Maxn],sum;
 18
 19 int mymin(int x,int y) {return x<y?x:y;}
 20
 21 void ins(int x,int y,int f)
 22 {
 23     t[++len].x=x;t[len].y=y;t[len].f=f;
 24     t[len].next=first[x];first[x]=len;t[len].o=len+1;
 25     t[++len].x=y;t[len].y=x;t[len].f=0;
 26     t[len].next=first[y];first[y]=len;t[len].o=len-1;
 27 }
 28
 29 void init()
 30 {
 31     len=0;
 32     memset(first,0,sizeof(first));
 33     st=300001;ed=st+1;sum=0;
 34     int x,now=ed;
 35     char cc;
 36     scanf("%d",&x);getchar();
 37     while(x--)
 38     {
 39         int c,y;
 40         scanf("%d",&c);getchar();
 41         ins(st,++now,c);sum+=c;
 42         while(scanf("%d%c",&y,&cc))
 43         {
 44             ins(now,y,INF);
 45             if(cc==‘\n‘) break;
 46         }
 47     }
 48     scanf("%d",&x);getchar();
 49     while(x--)
 50     {
 51         int c,y;
 52         scanf("%d",&c);getchar();
 53         ins(++now,ed,c);sum+=c;
 54         while(scanf("%d%c",&y,&cc))
 55         {
 56             ins(y,now,INF);
 57             if(cc==‘\n‘) break;
 58         }
 59     }
 60 }
 61
 62 queue<int > q;
 63 bool bfs()
 64 {
 65     while(!q.empty()) q.pop();
 66     memset(dis,-1,sizeof(dis));
 67     q.push(st);dis[st]=0;
 68     while(!q.empty())
 69     {
 70         int x=q.front();q.pop();
 71         for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
 72         {
 73             int y=t[i].y;
 74             if(dis[y]==-1)
 75             {
 76                 dis[y]=dis[x]+1;
 77                 q.push(y);
 78             }
 79         }
 80     }
 81     if(dis[ed]==-1) return 0;
 82     return 1;
 83 }
 84
 85 int ffind(int x,int flow)
 86 {
 87     if(x==ed) return flow;
 88     int now=0;
 89     for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
 90     {
 91         int y=t[i].y;
 92         if(dis[y]==dis[x]+1)
 93         {
 94             int a=ffind(y,mymin(flow-now,t[i].f));
 95             now+=a;
 96             t[i].f-=a;
 97             t[t[i].o].f+=a;
 98         }
 99     }
100     if(now==0) dis[x]=0;
101     return now;
102 }
103
104 void max_flow()
105 {
106     int ans=0;
107     while(bfs())
108     {
109         ans+=ffind(st,INF);
110     }
111     printf("%d\n",sum-ans);
112 }
113
114 int main()
115 {
116     int T,kase=0;
117     scanf("%d",&T);
118     while(T--)
119     {
120         init();
121         printf("Case %d:\n",++kase);
122         max_flow();
123         if(T) printf("\n");
124     }
125     return 0;
126 }

[LA3487]

  最后一行输出空行报WA也是坑死了。

2016-05-27 13:22:21

时间: 2024-11-17 00:18:42

【UVALive - 3487】 Duopoly(网络流-最小割)的相关文章

【bzoj3144】[Hnoi2013]切糕 网络流最小割

题目描述 输入 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R). 100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000. 输出 仅包含一个整数,表示在合法基础上最小的总不和谐值. 样例输入 2 2 2 1 6 1 6 1 2 6 2 6 样例输出 6 题目大意 给定一个p行q列的矩阵,每个位置可以

二分图&amp;网络流&amp;最小割等问题的总结

二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 带下界网络流 最小割问题的总结: *意义 1.加inf的边表示不能被割,通常用于体现某个点必须属于某个集合 连边(s,u,w)代表如果u不在s割的话需要付出代价w 2.连边(u,v,w)代表如果u在s割,v在t割需要付出代价w 但注意,如果u在t割,v在s割是不需要付出代价的. 那么如果连边(u,v,w)以及(v,u,w)则说明当u与v所属割不同的时候需要付出代价w *

HDU 2435 There is a war (网络流-最小割)

There is a war Problem Description There is a sea. There are N islands in the sea. There are some directional bridges connecting these islands. There is a country called Country One located in Island 1. There is another country called Country Another

【bzoj3630】[JLOI2014]镜面通道 对偶图+计算几何+网络流最小割

题目描述 在一个二维平面上,有一个镜面通道,由镜面AC,BD组成,AC,BD长度相等,且都平行于x轴,B位于(0,0).通道中有n个外表面为镜面的光学元件,光学元件α为圆形,光学元件β为矩形(这些元件可以与其他元件和通道有交集,具体看下图).光线可以在AB上任一点以任意角度射入通道,光线不会发生削弱.当出现元件与元件,元件和通道刚好接触的情况视为光线无法透过(比如两圆相切).现在给出通道中所有元件的信息(α元件包括圆心坐标和半径xi,yi,ri,β元件包括左下角和右上角坐标x1,y1,x2,y2

【bzoj2127】happiness 网络流最小割

题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. 输入 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值.第二个矩阵为n行m列 此矩阵的第i行

【bzoj2132】圈地计划 网络流最小割

题目描述 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值.更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益.另外不同的区域连在一起可以得到额外的收益,即如果区域(I,j)相邻(相邻

ZOJ3792_Romantic Value(网络流/最小割=最大流/找割边)

解题报告 题目传送门 题意: 给出一个无向图,以及起点与终点.要删除一些边使得起点与终点不连通,在删掉边的权值之和最小的情况下要求删除的边数尽量少. 求出一个比值:剩余边数权值和/删除的边数. 思路: 明显的让起点终点达不到就是一个最小割,用最大流可以求出. 但是求割边边数就不会了,没做过最小割的求割边问题. 割边一定是残留网络中零流的边,但零流不一定是割边. 飞神的想法很奇特.链接传送 可以把残留网络的零流的边设成容量为1,其他设成无穷,再求一次最大流.最后流量一定等于割边边数 另外: 还有一

HDU 4289 Control (网络流-最小割)

Control Problem Description You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to another one (the destination). You know their

POJ3469_Dual Core CPU(网络流/最小割=最大流/模版)----Dinic模版2.0

解题报告 题目传送门 题意: 双核CPU,n个模块,每个模块必须运行在某个CPU核心上,每个模块在cpu单核的消耗A和B,M对模块要共享数据,如果在同一个核心上不用消耗,否则需要耗费.安排N个模块,使得总耗费最小 思路: 将两个cpu核心看成源点和汇点,其他模块分别与源点汇点连线(表示每个模块可以在任意cpu上运行),m对模块分别连双向边,要使得模块只能在一个cpu上运行,就是找到一个割,源点和汇点必不联通,耗费最少就是最小割,最小割最大流原理转换成求最大流. 这题数据大,没优化TLE了,加了两

【bzoj4177】Mike的农场 网络流最小割

题目描述 Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中第i个牲畜围栏中的动物长大后,每只牛可以卖a[i]元,每只羊可以卖b[i]元,为了防止牛羊之间相互影响,Mike找到了m条规律,每条规律给出一个三元组(i, j, k)表示如果第i个围栏和第j个围栏养的是不同的动物,那么Mike就需要花费k的代价请人帮忙处理牛羊之间的影响.不过同时Mike也发现k条特殊的规则(S, a, b),表示如果S中所有牲畜