题目:http://acm.hdu.edu.cn/showproblem.php?pid=4647
题目大意:给你一个无向图,n个点,m条边,点上和边上都有权值,Alice和Bob从Alice开始轮流取点,不能取取过的点,取了某个点,就得到该点的值,如果某条边都被同一个人取了,那他就得到这条边的权值,每个人得决策都是最优,希望与对手之间的分差越大越好,然后输出最后Alice - Bob。
思路:若没有边权,则对点权从大到小排序即可。考虑边,将边权拆成两半加到它所关联的两个点的点权中即可。因为当两个人分别选择不同的点时,这一权值将互相抵消。
以上均摘自杭电解题报告。。 自己比赛的时候就觉得边好麻烦,死活也想不到原来可以这么处理这些边。。 = =
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 111111 ;
double val[MAXN];
bool cmp(double a,double b)
{
return a>b;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i = 1;i<=n;i++)
scanf("%lf",&val[i]);
int a,b;
double c;
for(int i = 1;i<=m;i++)
{
scanf("%d%d%lf",&a,&b,&c);
val[a] += c/2.0;
val[b] += c/2.0;
}
sort(val+1,val+1+n,cmp);
double ans = 0;
for(int i = 1;i<=n;i+=2)
{
ans += val[i]-val[i+1];
}
printf("%.0f\n",ans);
}
return 0;
}