贪心好题,表示不会做然后膜拜了一下PoPoQQQ的题解http://blog.csdn.net/popoqqq/article/details/44495319。
考虑每个点选对答案的贡献为w,不选的贡献为-w,每一条边两个端点都不选的贡献为-c,选一个端点的贡献为0,选两个端点的贡献为c,于是我们计算ans的时候先全部都减去,然后就变成了,一个点选的贡献为2w,不选的贡献为0,一条边两个端点都不选的贡献为0,选一个端点的贡献为c,选两个端点的贡献为2c,每个点的权值就等于2*w+c,于是每次选最大的就好了。
其实还有一种做法,可以把边权平分到两个端点,因为每条边要么属于一个人,要么属于两个人,而且答案要求差值,所以是正确的。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 10010
using namespace std;
long long a[maxn];
long long ans;
int n,m;
bool cmp(long long a,long long b)
{
return a>b;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
ans-=x;a[i]+=2*x;
}
for (int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
ans-=z;a[x]+=z;a[y]+=z;
}
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;i+=2) ans+=a[i];
printf("%lld\n",ans);
return 0;
}