首页 > 其他分享 >[ABC326G] Unlock Achievement

[ABC326G] Unlock Achievement

时间:2024-09-20 09:13:51浏览次数:3  
标签:成就 return ABC326G val int 源点 Unlock Achievement 技能

思路

题目&思考

翻译一下题目:已知有 n 个技能,每个技能可以耗费 \(c _ {i}\) 升一级,每个技能最多可以升到 ( $ 1\ \leq\ L_{i,j}\ \leq\ 5 $ ) ,升级的同事可以获得成就,共有 m 个成就,每个成就可以获得 \(c _ {i}\) 的收益,每个成就需要每个技能达到一定的限制,询问获得的奖励与所需成本之差。

看到有这么多点以及给出的条件十分繁杂的前提下,可以考虑网络流,对于网络流,最难的是网络流的建模。

网络流的建模:

题目所给的条件没有明显源点汇点,所以考虑设立一个超级源点 \(S\) 以及超级汇点 \(T\)。

由于每个技能可以升级,单个点不能处理每一级之间的关系。

考虑拆点

将每一个技能拆成五个点,代表此技能的五级,除第五级外每一级向自己的下一级连一条流量为 inf 的边(保证它不会被割掉)。

对于源点,其连的是花费,因为所有的技能一开始都是一级,所以在一级的时候不需要花费任何代价,超级源点 S 向除了第一级的所有点连一条流量为 \(c _ {i}\) 的边。

这样连边就可以保证每一级的最大流量是技能升级需要的花费。

对于汇点,由于成就的条件十分繁杂,对于每个成就,考虑新建节点 \(p_ {i}\),其限制条件可以转化为P1361 小M的作物,将每个成就需要的每个技能级数的点连向当前点 \(p_ {i}\),这样就保证了成就限制条件,最后每个 \(p_ {i}\) 向超级汇点连一条流量为 \(c _ {i}\) 的边,代表此成就的奖励。

所以综上所述,本题的建模规则:

1:将每个点拆成五个点,每一级向下一级连一条流量 inf 的边。

2:源点向每个技能每一级(除了第一级)连一条流量为 \(c _ {i}\) 的边。

3:对于每一个成就新建一个点,将其限制的技能级数连向这个点。

4:每一个代表成就的点向汇点连一条流量为 \(c _ {i}\) 的边。

这道题利用的便是网络流中的最小割,因为我们要求的是升级每个技能至某一级,最大化获得的奖励与所需成本之差,最小割求得的便是升级所用的花费+没有达成的成就之和,成就的总和 - dinic 求出的最小割=获得的奖励与所需成本之差。

在网络流中,最小割的数值上=最大流,所以可以跑一遍 dinic 板子,最后要求的答案就是所有的 \(c _ {i}\) 之和减去求得的最小割的值。

更多细节参见代码。

代码

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
#define inf 1e9
using namespace std;

inline int min(int x,int y){return x>y?y:x;}

int n,m,s,t,maxx=0;

int cnt=-1,res=0;;
struct N{
	int to,next,val; 
}; N p[800005];
int head[100005],cur[100005];
int c[55],a[55],d[10005];
int mapp[55][55];

inline void add(int a,int b,int c)
{
	++cnt;
	p[cnt].next=head[a];
	head[a]=cnt;
	p[cnt].to=b;
	p[cnt].val=c;
	return ;
}

inline int bfs()
{
	memset(d,-1,sizeof(d));
	queue<int> q;
	q.push(s); 
	d[s]=0;
	while(q.size()>0)
	{
		int u=q.front();
		q.pop();
		for(int i=head[u];i!=-1;i=p[i].next)
		{
			int v=p[i].to;
			if(d[v]==-1&&p[i].val>0)
			{
				d[v]=d[u]+1;
				q.push(v);
			}
		}
	}
	if(d[t]==-1) return 0;
	else return 1;
}

inline int dfs(int u,int limit)
{
	if(u==t||!limit) return limit;
	int flow=0,sum=0;
	for(int i=cur[u];i!=-1;i=p[i].next)
	{
		int v=p[i].to;
		cur[u]=i;
		if(d[v]==d[u]+1&&p[i].val>0)
		{
			sum=dfs(v,min(limit,p[i].val));
			limit-=sum;
			flow+=sum;
			p[i].val-=sum;
			p[i^1].val+=sum;
			if(!limit) break;
		}
	}
	if(!flow) d[u]=-1;
	return flow;
}

inline void dinic()
{
	int ans=0;
	while(bfs())
	{
		for(int i=0;i<=t;i++) cur[i]=head[i];//弧优化 
		ans+=dfs(s,inf); 
	}
	cout<<maxx-ans<<endl;
	return ;
}//板子

int main()
{
	memset(head,-1,sizeof(head));
	cin>>n>>m;
	s=0,t=5*n+m+1;//超级源点和超级汇点
	for(int i=1;i<=n;i++)
	{
		cin>>c[i];
		++res;
		for(int j=2;j<=5;j++)
		{
			res++;
			add(res-1,res,inf),add(res,res-1,0);
			add(s,res,c[i]),add(res,s,0);
		}
	}//拆点,建图规则1&2,点编号 1-5*n
	for(int i=1;i<=m;i++)
	{
		cin>>a[i];
		add(5*n+i,t,a[i]),add(t,5*n+i,0);
		maxx+=a[i];
	}//建图规则4,点编号5*n+1-5*n+m
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>mapp[i][j];
			if(mapp[i][j]>1) add(5*(j-1)+mapp[i][j],5*n+i,inf),add(5*n+i,5*(j-1)+mapp[i][j],0);
		}//第i个点点第j级的编号为5(i-1)+j; 
	}//建图规则3
	dinic();//板子
	
	return 0;
}

在题目点数众多,限制条件十分繁杂的情况下,都可以考虑使用最小割的方法。和这题处理方法类似的有:

P1646 [国家集训队] happiness

P4313 文理分科

P1361 小M的作物

P2057 [SHOI2007] 善意的投票

P1935 [国家集训队] 圈地计划

标签:成就,return,ABC326G,val,int,源点,Unlock,Achievement,技能
From: https://www.cnblogs.com/call-of-silence/p/18421815

相关文章

  • VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Serve
    VMwareESXi7.0U3qmacOSUnlocker集成驱动版更新OEMBIOS2.7支持WindowsServer2025VMwareESXi7.0U3qmacOSUnlocker&OEMBIOS2.7集成网卡驱动和NVMe驱动(集成驱动版)ESXi7.0U3标准版集成Intel网卡、RealtekUSB网卡和NVMe驱动请访问原文链接:h......
  • VMware ESXi 8.0U3 macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server
    VMwareESXi8.0U3macOSUnlocker集成驱动版更新OEMBIOS2.7支持WindowsServer2025VMwareESXi8.0U3macOSUnlocker&OEMBIOS2.7集成网卡驱动和NVMe驱动(集成驱动版)发布ESXi8.0U3集成驱动版,在个人电脑上运行企业级工作负载请访问原文链接:https://sy......
  • Earn or Unlock
    我们将操作过程中选择进行操作一的卡片称为“抛弃”,显然被抛弃的卡片的顺序无关紧要,所以如果我们确定了抛弃的卡片的编号,我们从小到大进行抛弃就好了证明非常简单,因为最终解锁了\(k\)张卡片,所以中途被抛弃了的卡片的\(v\)的和就是\(k-1\),而我们最终的得分就是前\(k\)张卡片的\(v......
  • VMware Workstation 17.6 Pro Unlocker & OEM BIOS 2.7 for Windows & Linux
    VMwareWorkstation17.6ProUnlocker&OEMBIOS2.7forWindows&Linux在Windows和Linux上运行macOSSequoia请访问原文链接:https://sysin.cn/blog/vmware-workstation-17-unlocker/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2024-09-03,版本17.6更新......
  • VMware Workstation 17.6 Pro macOS Unlocker & OEM BIOS 2.7 for Windows - 在 Windo
    VMwareWorkstation17.6PromacOSUnlocker&OEMBIOS2.7forWindows在Windows上运行macOSSequoia请访问原文链接:https://sysin.cn/blog/vmware-workstation-17-unlocker-windows/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2024-09-03,版本17.6更新,支......
  • VMware Workstation 17.6 Pro macOS Unlocker & OEM BIOS 2.7 for Linux - 在 Linux
    VMwareWorkstation17.6PromacOSUnlocker&OEMBIOS2.7forLinux在Linux上运行macOSSequoia请访问原文链接:https://sysin.cn/blog/vmware-workstation-17-unlocker-linux/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2024-09-03,版本17.6更新,支持虚拟......
  • VMware Workstation 17.6 Pro Unlocker & OEM BIOS 2.7 for Windows & Linux
    VMwareWorkstation17.6ProUnlocker&OEMBIOS2.7forWindows&Linux在Windows和Linux上运行macOSSequoia请访问原文链接:https://sysin.cn/blog/vmware-workstation-17-unlocker/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2024-09-03,版本13.6更......
  • VMware ESXi 8.0U3 macOS Unlocker 标准版和厂商定制版更新 OEM BIOS 2.7 支持 Window
    VMwareESXi8.0U3macOSUnlocker标准版和厂商定制版更新OEMBIOS2.7支持WindowsServer2025VMwareESXi8.0U3macOSUnlocker&OEMBIOS2.7标准版和厂商定制版ESXi8.0U3标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitach......
  • VMware ESXi 6.7U3u macOS Unlocker 标准版和厂商定制版更新 OEM BIOS 2.7 支持 Windo
    VMwareESXi6.7U3umacOSUnlocker&OEMBIOS2.7标准版和厂商定制版UIfixESXi6.7U3u标准版,Dell(戴尔)、HPE(慧与)OEM定制版请访问原文链接:https://sysin.org/blog/vmware-esxi-6-oem/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2024-09-01,更新......
  • VMware ESXi 8.0U3 macOS Unlocker & OEM BIOS Dell (戴尔) 定制版
    VMwareESXi8.0U3macOSUnlocker&OEMBIOSDell(戴尔)定制版ESXi8.0U3标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitachi(日立)、Fujitsu(富士通)、NEC(日电)、Huawei(华为)、xFusion(超聚变)OEM定制版请访问原文链接:h......