【题解 && 海亮集训 && 刷题】 阿狸和桃子的游戏

题目传送门

题目描述:

阿狸和桃子正在玩一个游戏,游戏是在一个带权图 G=(V,E)G=(V,E) 上进行的,设节点权值为 w(v)w(v),边权为 c(e)c(e)。游戏规则是这样的:

阿狸和桃子轮流将图中的顶点染色,阿狸会将顶点染成红色,桃子会将顶点染成粉色。已经被染过色的点不能再染了,而且每一轮都必须给一个且仅一个顶点染色。

为了保证公平性,节点的个数 NN 为偶数。

经过 N/2N/2 轮游戏之后,两人都得到了一个顶点集合。对于顶点集合 SS,得分计算方式为 ∑v∈Sw(v)+∑e=(u,v)且u,v∈Sc(e)∑v∈Sw(v)+∑e=(u,v)且u,v∈Sc(e)

由于阿狸石头剪子布输给了桃子,所以桃子先染色。两人都想要使自己的分数比对方多,且多得越多越好。如果两人都是采用最优策略的,求最终桃子的分数减去阿狸的分数。


分析:

说实话这题之所以被评判为 N O I + NOI+ NOI+难度的题目,是因为它是考思维的。

看到点权和边权,第一眼很容易想到图论
然而并不是

  • 我们考虑如何转化:
    对于一条边权,只有选到了边权上的两个点才能得到这条边权,但如果只选一个点,却什么也得不到

对于这个性质,我们很容易 想到将边权平分给两个点。
接下来给出如何证明:

  • 对于一条边的两个端点 ,我们把边权的一半赋给它们
  • 这样如果两个点都选那么贡献就是 w ( u ) + w ( v ) + c ( e ( u , v ) ) w(u)+w(v)+c(e(u,v)) w(u)+w(v)+c(e(u,v))
  • 如果只选择其中的一个点,贡献就是:
    [ w ( u ) + c ( e ( u , v ) ) 2 ] − [ w ( v ) + c ( e ( u , v ) ) 2 ] = w ( u ) − w ( v ) [w(u)+\frac {c(e(u,v))}2]-[w(v)+\frac {c(e(u,v))}2]=w(u)-w(v) [w(u)+2c(e(u,v))][w(v)+2c(e(u,v))]=w(u)w(v)
  • 贡献不变
  • 证毕

所以很显然可以把边权平均赋给两个点,然后贪心排序即可。


Code

#include<bits/stdc++.h>
using namespace std;
int n,m;
double a[10101010];

int main(){
	scanf("%d %d",&n,&m);
    for (int i=1;i<=n;i++) scanf("%lf",&a[i]);
    for (int i=1,x,y;i<=m;i++){
	    double z;
	    scanf("%d %d %lf",&x,&y,&z);
	    a[x]+=z/double(2);
	    a[y]+=z/double(2);
	}
	sort(a+1,a+n+1);
	double ans=0;
	for (int i=2;i<=n;i+=2)
	  ans+=a[i]-a[i-1];
	printf("%d",(int)ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值