CF 103E Buying Sets 最大权闭合子图,匹配 难度:4
http://codeforces.com/problemset/problem/103/E
这道题首先一看就很像是最大权闭合子图,但是我们可以认为现在有两种点,数字和集合点,我们需要消除数字点的影响才能直接运用最大权闭合子图.
进行二分匹配,使得每个集合都唯一匹配一个数字,买下一个集合点,则意味着该集合中所有数字的对应匹配集合点都要被买下,也就是可以建立一个新图,其中某个集合点向对应数字代表的集合点连单向边,可以证明对于任意权闭合子图中的集合点,集合中所有数字的对应匹配集合点都已经在这个权闭合子图中.对这个新图的所有价格取反,答案即最大权的负数
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=305;
const int maxm=2*maxn+maxn*maxn;
const int sups=303,supt=304;
const int inf=0x6ffffff; int n;//original aspects
int price[maxn];
int st[maxn][maxn],nst[maxn]; int mch[2*maxn];//Match
bool vis[2*maxn]; int first[maxn],elen;//maximum flow
struct edge{
int nxt,f,t,c;
}e[maxm];
int dis[maxn],gap[maxn]; bool subMatch(int s){
vis[s]=true;
for(int j=0;j<nst[s];j++){
int t=st[s][j]+n;
if(vis[t]||mch[t]==s)continue;
if(mch[t]==0||(!vis[mch[t]]&&subMatch(mch[t]))){
mch[t]=s;
mch[s]=t;
return true;
}
}
return false;
}
void Match(){
for(int i=1;i<=n;i++){
if(mch[i]==0){
memset(vis,false,sizeof(vis));
subMatch(i);
}
}
} void addedge(int f,int t,int c){
e[elen].nxt=first[f];
e[elen].f=f;
e[elen].t=t;
e[elen].c=c;
first[f]=elen++;
}
void build(){
for(int i=1;i<=n;i++){
if(price[i]>=0){
addedge(sups,i,price[i]);
addedge(i,sups,0);
}
else {
addedge(i,supt,-price[i]);
addedge(supt,i,0);
}
for(int j=0;j<nst[i];j++){
int t=mch[st[i][j]+n];
addedge(i,t,inf);
addedge(t,i,0);
}
}
}
int dfs(int s,int flow){
if(s==supt)return flow;
int mindis=n;
int tflow=flow,sub;
for(int p=first[s];p!=-1;p=e[p].nxt){
int t=e[p].t;
if(e[p].c>0){
if(dis[t]+1==dis[s]){
sub=dfs(t,min(tflow,e[p].c));
e[p].c-=sub;e[p^1].c+=sub;
tflow-=sub;
if(dis[sups]>n)return flow-tflow;
if(tflow<=0)break;
}
mindis=min(mindis,dis[t]);
}
}
if(flow==tflow){
--gap[dis[s]];
if(gap[dis[s]]==0)dis[sups]=n+1;
else{
dis[s]=mindis+1;
++gap[dis[s]];
}
}
return flow-tflow;
}
int maxflow(){
int flow=0;
gap[0]=n+2;
while(dis[sups]<=n){
flow+=dfs(sups,inf);
}
return flow;
} int main(){
int ans=0;
memset(first,-1,sizeof(first));
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",nst+i);
for(int j=0;j<nst[i];j++){
scanf("%d",st[i]+j);
}
}
for(int i=1;i<=n;i++){
scanf("%d",price+i);
price[i]*=-1;
if(price[i]>=0)ans+=price[i];
} Match();
build();
ans=maxflow()-ans;
printf("%d\n",ans);
return 0;
}
CF 103E Buying Sets 最大权闭合子图,匹配 难度:4的更多相关文章
- 洛谷 P4174 [NOI2006]最大获利 && 洛谷 P2762 太空飞行计划问题 (最大权闭合子图 && 最小割输出任意一组方案)
https://www.luogu.org/problemnew/show/P4174 最大权闭合子图的模板 每个通讯站建一个点,点权为-Pi:每个用户建一个点,点权为Ci,分别向Ai和Bi对应的点连 ...
- Solution -「最大权闭合子图」做题随笔
T1 小 M 的作物 先从简化题目入手,考虑先去掉 \(c\) 的额外收益.然后尝试将所有作物种在 \(B\), 则目前得到了 \(\sum \limits_{i = 1} ^n b_i\) 的收益. ...
- BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...
- HDU 3879 Base Station(最大权闭合子图)
经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...
- [BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1497 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以 ...
- HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4971 Description There's a company with several ...
- HDU5855 Less Time, More profit(最大权闭合子图)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5855 Description The city planners plan to build ...
- HDU5772 String problem(最大权闭合子图)
题目..说了很多东西 官方题解是这么说的: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得分) 第二类:原串中的n个点每个 ...
- SCU3109 Space flight(最大权闭合子图)
嗯,裸的最大权闭合子图. #include<cstdio> #include<cstring> #include<queue> #include<algori ...
随机推荐
- JavaWeb学习总结(十)--JDBC之MySQL大数据
一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 但是,在mysql ...
- MyBatis——解决字段名与实体类属性名不相同的冲突
原文:http://www.cnblogs.com/xdp-gacl/p/4264425.html 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况 ...
- Spring多数据源的配置和使用
1. 配置多个数据源 最近开发一个数据同步的小功能,需要从A主机的Oracle数据库中把数据同步到B主机的Oracle库中.当然能够用dmp脚本或者SQL脚本是最好,但是对于两边异构的表结构来说,直接 ...
- nfs服务器设置
前段时间重新装了一下Linux系统,结果导致NFS服务器总是挂在不成功,于是粗略学习了一下: NFS服务需要两个软件包: 1.nfs-utiles-* 2.portmap-* nfsd:它是基本的NF ...
- C++疑难杂症
1.如果在类成员函数外部显示的调用其父类的某个接口. 2.对于一个父类的成员, 子类如何在构造函数中对其进行特殊的定制生成. 3.对于一个需要用常量来声明的类型, 如何定义这个常量. 比如int ...
- css读书笔记2:css工作原理
css就是一种先选择html元素,然后设定选中元素css属性的机制.css选择符合要应用的样式构成一条css规则. 为文档添加样式的3种方法: 1.行内样式,直接写在特定标签的style属性中:2.嵌 ...
- noip赛前小结4
真正的勇士,敢于面对惨淡的人生. 真正的OIer,敢于做ccop的题. 有种凄凉叫做这道数学题已经超出了我语文的理解范围. 有种愤怒叫做ccop类的信息题已经超出了我语文的理解范围和数学的理解范围. ...
- Java并发编程:并发容器之ConcurrentHashMap
转载: Java并发编程:并发容器之ConcurrentHashMap JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的 ...
- word-break:break-all和word-wrap:break-word的区别
了解word-break属性 /* 关键字值 */ word-break: normal; word-break: break-all; word-break: keep-all; /* 全局值 */ ...
- linux下如何优雅的挂载一个外界设备(比如优盘)
最近从事linux,实验室一个破服务器,能连上网,但是输入这样的命令: yum -y install gcc yum -y install gcc-c++ ,居然说是没有这样的镜像,也罢 ...