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

题目分析:如果两家公司的申请之间没有任何矛盾,那么最大的收益就是所有的申请费用之和。如果某些列表之间有矛盾,那么就需要用最小的代价使两家公司的申请没有任何矛盾。将每一条申请视作一个点,增加源点s和汇点t,从s向甲公司的每一条申请连一条弧,容量为该申请的费用;从乙公司的每一条申请向t连一条弧,容量为每条申请对应的费用;然后对于甲公司的每一条申请,向所有与它矛盾的申请(只可能是乙公司的申请)连一条弧,容量为无穷大。那么,最小割便是这个最小代价,用申请费用总和减去最小代价便是最大收益。

代码如下:

# include<iostream>
# include<cstdio>
# include<cmath>
# include<string>
# include<vector>
# include<list>
# include<set>
# include<map>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std; # define LL long long
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b) const double inf=1e30;
const int INF=1<<30;
const int N=6005; /////////////////////////////////
struct Edge
{
int fr,to,cap,fw;
Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){}
};
struct Dinic{
vector<Edge>edges;
vector<int>G[N];
int d[N],vis[N],cur[N];
int s,t; void init(int n,int s,int t)
{
this->s=0,this->t=t;
REP(i,0,n) G[i].clear();
edges.size();
} void addEdge(int u,int v,int cap)
{
edges.push_back(Edge(u,v,cap,0));
edges.push_back(Edge(v,u,0,0));
int len=edges.size();
G[u].push_back(len-2);
G[v].push_back(len-1);
} bool BFS()
{
CL(vis,0);
d[s]=0;
vis[s]=1;
queue<int>q;
q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();
REP(i,0,G[x].size()){
Edge &e=edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.fw){
d[e.to]=d[x]+1;
vis[e.to]=1;
q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t||a==0) return a;
int flow=0,f;
for(int &i=cur[x];i<G[x].size();++i){
Edge &e=edges[G[x][i]];
if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.fw)))>0){
e.fw+=f;
edges[G[x][i]^1].fw-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
} int MaxFlow()
{
int flow=0;
while(BFS()){
CL(cur,0);
flow+=DFS(s,INF);
}
return flow;
}
};
Dinic dinic;
//////////////////////////////////// int sum,maxn;
int a[300005],b[300005];
bool vis[3005][3005];
int p1[3005],p2[3005]; void init()
{
maxn=sum=0;
CL(a,0);
CL(b,0);
} bool read(int &x)
{
x=0;
char c;
while(c=getchar()){
if(c=='\n') return false;
if(c==' ') return true;
x=x*10+c-'0';
}
} int main()
{
int T,n,m,cas=0;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
REP(i,1,n+1){
scanf("%d",&p1[i]);
sum+=p1[i];
int x;
getchar();
while(read(x))
{
a[x]=i;
maxn=max(maxn,x);
}
a[x]=i;
maxn=max(maxn,x);
}
scanf("%d",&m);
dinic.s=0,dinic.t=n+m+1;
REP(i,1,m+1){
scanf("%d",&p2[i]);
sum+=p2[i];
int x;
while(read(x))
{
b[x]=i;
maxn=max(maxn,x);
}
b[x]=i;
maxn=max(maxn,x);
}
dinic.init(n+m+2,0,n+m+1);
REP(i,1,n+1) dinic.addEdge(0,i,p1[i]);
REP(i,1,m+1) dinic.addEdge(i+n,n+m+1,p2[i]);
CL(vis,false);
REP(i,1,maxn+1){
if(!a[i]||!b[i]||vis[a[i]][b[i]]) continue;
vis[a[i]][b[i]]=true;
dinic.addEdge(a[i],b[i]+n,INF);
}
printf("Case %d:\n",++cas);
printf("%d\n",sum-dinic.MaxFlow());
if(T) printf("\n");
}
return 0;
}

  

UVALive-3487 Duopoly(最小割)的更多相关文章

  1. UVaLive 3487 Duopoly (最小割)

    题意:有两个公司A和B在申请一些资源,现在给出两个公司所申请的内容,内容包括价钱和申请的资源 ,现在你做为官方,你只能拒绝一个申请或者接受一个申请,同一个资源不能两个公司都拥有,且申请的资源不能只给部 ...

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

    Description The mobile network market in country XYZ used to be dominated by two large corporations, ...

  3. 【LA 3487】Duopoly(图论--网络流最小割 经典题)

    题意:C公司有一些资源,每种只有1个,有A.B两个公司分别对其中一些资源进行分组竞标,每组竞标对一些资源出一个总价.问C公司的最大收益. 解法:最小割.将A公司的竞标与源点相连,B公司的与汇点相连,边 ...

  4. UVALive 5099 Nubulsa Expo 全局最小割问题

    B - Nubulsa Expo Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit S ...

  5. UVa1212 Duopoly(最小割)

    题目大概说有两家通讯公司,它们分别有几个投标,投标各有价值且各个投标都包含几个频道,相同公司的各个投标包含频道都是互不相同的,而频道不能被同时选用.问怎么选择采取哪家公司哪些投标使得价值最大. 如此建 ...

  6. UVALive 5905 Pool Construction 最小割,s-t割性质 难度:3

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  7. UVALive 3661 Animal Run(最短路解最小割)

    题意:动物要逃跑,工作人员要截断从START(左上角)到END(右下角)的道路,每条边权表示拦截该条道路需要多少工作人员.问最少需要多少人才能完成拦截. 通俗地讲,就是把图一分为二所造成消耗的最小值. ...

  8. UVALive 5099 Nubulsa Expo 全球最小割 非网络流量 n^3

    主题链接:点击打开链接 意甲冠军: 给定n个点m条无向边 源点S 以下m行给出无向边以及边的容量. 问: 找一个汇点,使得图的最大流最小. 输出最小的流量. 思路: 最大流=最小割. 所以题意就是找全 ...

  9. UVALive 7264 Kejin Game 网络流+最小割

    Kejin Game 题意:一个人有一颗技能树, 现在它想修练到某个技能 (假设为x), 现在修一个技能有3种方式: 1, 将该技能的前置技能都学完了,才能学该技能. 2, 取消一个技能 与 另一个技 ...

随机推荐

  1. sql 中如何将返回的记录某一条置顶

    将table1中id 为2的记录置顶select * from table1order by case when id='2' then 0 else 1 end 例子:将已发布的置顶,status  ...

  2. 用Oracle实现ASH的数据透视图

    11g里面有个很有用的新特性,对数据透视图的支持. 简单而言,它可以实现宽表和窄表之间的转化.举一个例子,有一张表记录了全校所有班级所有学生的成绩(A,B,C,D,E),现在想统计每个班级里每个分数级 ...

  3. yum localinstall 安装mysql8.0

    MySQL :: MySQL 8.0 Reference Manual :: 2.5.1 Installing MySQL on Linux Using the MySQL Yum Repositor ...

  4. R-CNN论文详解 - CSDN博客

    废话不多说,上车吧,少年 paper链接:Rich feature hierarchies for accurate object detection and semantic segmentatio ...

  5. Flask wtform组件

    Wtforms简介 WTForms是一个支持多个web框架的form组件 主要能够帮助我们生成html标签 对数据进行验证 安装 pip install wtforms Wtforms的使用 这里借助 ...

  6. socket套接字TCP协议传输-案例测试

    术语: 套接字接口:socket,是一个IP地址和一个端口号的组合,套接字可以唯一标识整个Internet中的一个网络进程. TCP连接:一对套接字接口(一个用于接收,一个用于发送)可定义面向连接的协 ...

  7. IOS 自己定义UITableView

    依据不同须要,须要使用tableview的结构,可是里面每个cell,又须要自己的样式.所以学习了一下如何把自定义的cell加到tableview里面 首先要自己创建一个类,继承UITableView ...

  8. python之sqlalchemy使用

    一.介绍 SQLAlchemy是一个基于Python实现的ORM框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然后使用数据API执行SQL并 ...

  9. Spark的RDD原理以及2.0特性的介绍

    转载自:http://www.tuicool.com/articles/7VNfyif 王联辉,曾在腾讯,Intel 等公司从事大数据相关的工作.2013 年 - 2016 年先后负责腾讯 Yarn ...

  10. 图:无向图(Graph)基本方法及Dijkstra算法的实现 [Python]

    一般来讲,实现图的过程中需要有两个自定义的类进行支撑:顶点(Vertex)类,和图(Graph)类.按照这一架构,Vertex类至少需要包含名称(或者某个代号.数据)和邻接顶点两个参数,前者作为顶点的 ...