首页 > 其他分享 >CF103E Buying Sets(最大权闭合子图模型)

CF103E Buying Sets(最大权闭合子图模型)

时间:2024-02-12 16:55:38浏览次数:29  
标签:return int 权值 子图 Sets 集合 include CF103E define

题意简述

有 \(n\) 个元素和 \(n\) 个集合,保证任意 \(k\) 个集合的并 \(\ge k\)。

每个集合有权值 \(a_i\),你需要选出一些集合使得集合数等于集合并大小,并在此基础上最小化选出的集合权值和。

\(n\le 300,|a_i|\le 10^6\)。

分析

将集合和元素看成物品,我们发现,若选择了一个集合,则我们要强制选择集合内的元素,这刚好是闭合子图的定义,将集合向集合内包含的点连边,题目相当于求最小权闭合子图,将权值取反后就是最大权闭合子图,最小割求解。如何求解最大权闭合子图及证明

继续考虑如何满足选出集合大小等于并集大小的限制。发现题目保证任意 \(k\) 个集合的并 \(\ge k\),这样我们就相当于最小化选出的并集大小最小。考虑给每个元素赋上一个额外的权值,为了强制让选出的并集大小最小,我们要让这个额外权值大小比所有集合权值之和还要大,让其为 \(inf\),这里 \(inf\) 是任意一个 \(\ge 3\times10^8\) 的值(注意由于最终求的是最大权闭合子图,所以实际建图中这个权值是 \(-inf\),以下额外赋的权值大小皆为取反前的权值)。为了不影响答案,同样给每个集合赋权 \(-inf\),然后这道题就做完了。

注意:

  • 实际建图中由于集合和元素间的边不能断(而额外赋的权值只是为了不多断,实际问题中是必须要断的),因此也要给这些边赋无穷大的权值,而且比 \(inf\) 还要大,否则会出现断掉集合和元素之间的边比割掉元素与汇点的边更优的情况。
  • 由于可以选空集,所以答案要与 \(0\) 取 max。
点击查看代码
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<unordered_map>
#include<vector>
#include<queue>
#include<bitset>
#include<set>
#include<ctime>
#include<random>
#define x1 xx1
#define y1 yy1
#define IOS ios::sync_with_stdio(false)
#define ITIE cin.tie(0);
#define OTIE cout.tie(0);
#define FlushIn fread(Fread::ibuf,1,1<<21,stdin)
#define FlushOut fwrite(Fwrite::obuf,1,Fwrite::S-Fwrite::obuf,stdout)
#define PY puts("Yes")
#define PN puts("No")
#define PW puts("-1")
#define P__ puts("")
#define PU puts("--------------------")
#define popc __builtin_popcount
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define gc getchar
#define pc putchar
#define pb emplace_back
#define lowb lower_bound
#define uppb upper_bound
#define rep(a,b,c) for(int a=(b);a<=(c);a++)
#define per(a,b,c) for(int a=(b);a>=(c);a--)
#define reprange(a,b,c,d) for(int a=(b);a<=(c);a+=d)
#define perrange(a,b,c,d) for(int a=(b);a>=(c);a-=d)
#define graph(i,j,k,l) for(int i=k[j];i;i=l[i].nxt)
#define lowbit(x) (x&-x)
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define mem(x,y) memset(x,y,sizeof x)
//#define double long double
#define int long long
//#define int __int128
using namespace std;
typedef long long i64;
bool greating(int x,int y){return x>y;}
bool greatingll(long long x,long long y){return x>y;}
bool smallingll(long long x,long long y){return x<y;}
namespace Fread {
	const int SIZE=1<<21;
	char ibuf[SIZE],*S,*T;
	inline char getc(){if(S==T){T=(S=ibuf)+fread(ibuf,1,SIZE,stdin);if(S==T)return '\n';}return *S++;}
}
namespace Fwrite{
	const int SIZE=1<<21;
	char obuf[SIZE],*S=obuf,*T=obuf+SIZE;
	inline void flush(){fwrite(obuf,1,S-obuf,stdout);S=obuf;}
	inline void putc(char c){*S++=c;if(S==T)flush();}
	struct NTR{~NTR(){flush();}}ztr;
}
/*#ifdef ONLINE_JUDGE
#define getchar Fread::getc
#define putchar Fwrite::putc
#endif*/
inline int rd(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}return x*f;
}
inline void write(int x,char ch='\0'){
	if(x<0){x=-x;putchar('-');}
	int y=0;char z[40];
	while(x||!y){z[y++]=x%10+48;x/=10;}
	while(y--)putchar(z[y]);if(ch!='\0')putchar(ch);
}
bool Mbg;
const int maxn=605,maxm=4e5+5,inf=0x3f3f3f3f;
const long long llinf=0x3f3f3f3f3f3f3f3f;
int n,m,S,T;
namespace MaxFlow{
	struct edge{
		int to,nxt,w;
	}a[maxm];
	int head[maxn],edges;
	void add_edge(int x,int y,int z){
		a[++edges]=(edge){y,head[x],z};
		head[x]=edges;
	}
	void add(int x,int y,int z){add_edge(x,y,z),add_edge(y,x,0);}
	int dis[maxn];
	int rou[maxn];
	void init(){
		rep(i,1,T)head[i]=0;edges=1;
	}
	bool bfs(){
		rep(i,1,T)dis[i]=0;
		queue<int>q;
		q.push(S),dis[S]=1;
		while(!q.empty()){
			int now=q.front();q.pop();
			rou[now]=head[now];
			graph(i,now,head,a){
				int u=a[i].to;
				if(a[i].w&&!dis[u]){
					dis[u]=dis[now]+1;
					if(u==T)return 1;
					q.push(u);
				}
			}
		}
		return 0;
	}
	int dfs(int x,int flow){
		if(x==T)return flow;
		int res=0;
		for(int &i=rou[x];i;i=a[i].nxt){
			int u=a[i].to;
			if(a[i].w&&dis[u]==dis[x]+1){
				int tmp=dfs(u,min(a[i].w,flow));
				flow-=tmp,res+=tmp,a[i].w-=tmp,a[i^1].w+=tmp;
				if(!flow)return res; 
			}
		}
		return res;
	}
	int maxflow(){
		int res=0;
		while(bfs())res+=dfs(S,llinf);
		return res;
	}
}
using namespace MaxFlow;
void solve_the_problem(){
	n=rd(),S=2*n+1,T=2*n+2;init();
	rep(i,1,n){
		int x=rd(),y;
		rep(j,1,x)y=rd(),add(i,y+n,llinf);
	}
	int ans=0;
	rep(i,1,n){int x=rd();add(S,i,inf-x),ans+=inf-x;}
	rep(i,1,n)add(i+n,T,inf);
	ans-=maxflow();
	write(min(0ll,-ans));
}
bool Med;
signed main(){
//	freopen(".in","r",stdin);freopen(".out","w",stdout);
//	fprintf(stderr,"%.3lfMB\n",(&Mbg-&Med)/1048576.0);
	int _=1;while(_--)solve_the_problem();
}
/*

*/

标签:return,int,权值,子图,Sets,集合,include,CF103E,define
From: https://www.cnblogs.com/dcytrl/p/18013965

相关文章

  • ABC306F Merge Sets
    原题链接分析观察要求的式子:\(\sum_{1\leqi\ltj\leqN}f(S_i,S_j)\),发现可以拆成每一个集合\(S_i\)的贡献的和。那么我们考虑每一个集合\(S_i\)的贡献。显然,对于每一个\(S_i\),其贡献就是\(\sum_{i\ltj\leqN}f(S_i,S_j)\),也就是它与其后每一个集合\(S_j\)的......
  • QSplitter 分割 组件之setStretchFactor方法
    原型:voidQSplitter::setStretchFactor(intindex,intstretch)翻译:将索引位置的部件的大小策略更新为具有拉伸因子stretch。stretch不是实际的拉伸因子;实际的拉伸因子是通过将部件的初始大小乘以stretch来计算的。根据实际情况可知,如果俩个控件默认大小一样,若下标0的拉伸因......
  • 无涯教程-Swift - 集合(Sets)
    Swift4Sets用于存储相同类型的不同值,但它们没有数组的确定顺序,如果要确保没有重复的值,则可以使用Set集合而不是数组。创建Set集您可以使用以下初始化语法创建一个特定类型的空集-varsomeSet=Set<Character>()//字符可以替换为set的数据类型。访问和修改您可以使用......
  • 无涯教程-Scala Sets函数
    ScalaSets是同一类型的不同元素的集合,换句话说,集合是不包含重复元素的集合。默认情况下,Scala使用不可变的Set。如果要使用可变Set,则必须显式导入scala.collection.mutable.Set类,如果要在同一集合中同时使用可变集和不可变集,则可以继续将不可变集称为Set,但可以将可变集称为......
  • scikit-learn.datasets 机器学习库
    scikit-learn是一个用于Python的机器学习库,提供了大量用于数据挖掘和数据分析的工具。以下是对这些函数和方法的简要描述:clear_data_home:清除数据集目录的内容。dump_svmlight_file:将数据集保存为SVMLight格式的文件。fetch_20newsgroups:下载20个新闻组的文本数据集。f......
  • Unity的StreamAssets文件夹
    StreamAssets是一个特殊的文件夹,其中的内容在Unity打包的时候并不会被压缩,完整的带入包体介绍在做一个根据可变配置进行操作的功能时,突然发现在windows中正常的功能在mac上失效了,而且还是部分mac失效。发现StreamAssets在mac某个版本以上就不支持写操作了,搜了一下网上的资料......
  • vscode windows CMakePresets.json
    vscode在windows下使用Ninja编译配置,使用VisualStudio编译环境。来源:CMakePresets.json参考:在VisualStudio中使用CMake预设进行配置和生成--示例文件CMakePresets.json{"version":2,"configurePresets":[{"name":"base","......
  • Android setStatusBarDisable
    Android中的setStatusBarDisable方法详解在Android开发中,我们经常需要定制状态栏的显示效果,有时甚至需要禁用状态栏。Android提供了setStatusBarDisable方法来实现禁用状态栏的功能。什么是状态栏状态栏是Android设备上显示系统状态信息的区域,通常位于屏幕的顶部。状态栏显示包......
  • uni.setStorageSync在登录页面设置缓存,第一次进入首页在onload里面获取不到缓存数据的
    在onLoad里面获取不到缓存:onLoad(option){consttoken=uni.getStorageSync('token');if(!token){uni.showToast({title:"请先登录",icon:"error",......
  • 【开源项目推荐】——纯中文本地GPT知识库搭建项目.assets
    大家好,我是独孤风。又到了本周的开源项目推荐。近一年多的时间,人工智能迎来了大爆发。GPT相关的大模型的发展让很多领域都发生了巨大的变化。但是虽然GPT的自然语言识别功能异常的强大,但回答给我们的知识内容并不尽如人意。那么,有没有可以在本地部署搭建的AI知识库项目呢?今天为......