题目描述
阿狸和桃子正在玩一个游戏,游戏是在一个带权图G=(V, E)上进行的,设节点权值为w(v),边权为c(e)。游戏规则是这样的:
-
阿狸和桃子轮流将图中的顶点染色,阿狸会将顶点染成红色,桃子会将顶点染成粉色。已经被染过色的点不能再染了,而且每一轮都必须给一个且仅一个顶点染色。
-
为了保证公平性,节点的个数N为偶数。
-
经过N/2轮游戏之后,两人都得到了一个顶点集合。对于顶点集合S,得分计算方式为sum_{v in S}w(v) + sum_{e=(u,v)in E land u,vin S}c(e)v∈S∑w(v)+e=(u,v)∈E∧u,v∈S∑c(e)
由于阿狸石头剪子布输给了桃子,所以桃子先染色。两人都想要使自己的分数比对方多,且多得越多越好。如果两人都是采用最优策略的,求最终桃子的分数减去阿狸的分数。
题解
-
把一条边的边权各一半加到两个顶点上,然后每个人选的时候,贪心的选取点权最大的点即可
-
为什么是对的?如果一条边的两个顶点被同一个人选上了,那么它就会额外提供等同于边权的贡献
-
否则的话,两个人每人都有一半边权的收益,相当于这条边谁也没给
代码
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int n,m,x,y,ans,sum,k,z,a[10010]; 5 int main() 6 { 7 scanf("%d%d",&n,&m); 8 for (int i=1;i<=n;i++) scanf("%d",&k),a[i]=k<<1; 9 for (int j=1;j<=m;j++) scanf("%d%d%d",&x,&y,&z),a[x]+=z,a[y]+=z; 10 sort(a+1,a+1+n); 11 for (int i=n;i>=1;i-=2) ans+=a[i]-a[i-1]; 12 printf("%d",ans/2); 13 }