BZOJ 2563 阿狸和桃子的游戏

mac2022-06-30  156

目录

BZOJ 2563 阿狸和桃子的游戏题意题解Code

BZOJ 2563 阿狸和桃子的游戏

题目传送门1

题意

给出一个图,每个点有点权\(v_i\),每条边有边权\(c_i\),两个人轮流选点,选择一个点可以获得这个点的点权,一条边的两个点如果都被一个人选了,那么这个人会获得这条边的边权。两者都采取最优的方案,问后手的分数减先手的分数是多少。

题解

看了题解之后感觉这道题目好妙啊。我们先分析对于一个人对一个点的选择对答案造成的影响: 1.如果一个点被这个人选择了,那么它的贡献是\(v_i\),如果这个点没有被选择,那么他的贡献是\(-v_i\)。 2.如果一条边的两个端点都被这个人选择了,那么它的贡献是\(c_i\),如果分别被两个人选择了,那么它的贡献是\(0\),如果都被另一个人选择了,那么它的贡献是\(-c_i\)。 而题目要我们求的两者的分数差,于是我们可以将\(ans\)减去所有的贡献,先默认由先手选择了,于是后手的选择对答案的影响会变成这样: 1.如果一个点被这个人选择了,那么它的贡献是\(2v_i\),否则贡献是\(0\)。 2.如果一条边的两个端点都被这个人选择了,那么它的贡献是\(2c_i\),如果分别被两个人选择了,那么它的贡献是\(c_i\),如果都被另一个人选择了,那么它的贡献是\(0\)。 这样做了改变之后,我们就可以把一个点的点权改为\(2v_i+\sum_{e=(i,v)} c(e)\),那么选择了这个点之后,获得的贡献仍然还是和之前一样的,并且不用考虑边权。然后我们就可以贪心的选择点,最后统计一下答案即可。

Code

#include <bits/stdc++.h> using namespace std; typedef long long ll; bool Finish_read; template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;} template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x+'0');} template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');} template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);} /*================Header Template==============*/ #define PAUSE printf("Press Enter key to continue..."); fgetc(stdin); const int N=1e5+500; int n,m; int val[N]; int ans=0; /*==================Define Area================*/ int main() { read(n);read(m); for(int i=1;i<=n;i++) read(val[i]),ans-=val[i],val[i]*=2; for(int i=1,u,v,c;i<=m;i++) read(u),read(v),read(c),ans-=c,val[u]+=c,val[v]+=c; sort(val+1,val+1+n); for(int i=2;i<=n;i+=2) ans+=val[i]; printf("%d\n",ans); return 0; }

转载于:https://www.cnblogs.com/Apocrypha/p/9580493.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)