传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=2563
题解
在没好好想过这道题之前千万不要看题解!
这是一道神奇的贪心题,一开始我想着对点和边排序,然后考虑是拿点还是不让别人拿边,但由于一个点连着很多边,有点复杂,我也不知道这个方法对不对,然后我瞄了一眼XJJ的博客,一下子就懂了。。。
对于一条边上的权值,我们将它分成两半分别放到左右端点上,然后直接排序点就行了。因为点必须要染完,如果同一个人取了一条边的两个端点,则获得边权,如果两个人一人取了一个端点的话,对他们的差,毫无影响。于是这样贪是对的。
之前做过一道类似的网络流题,也差不多是这个套路,但居然没想起来。。
代码
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>
#define maxn 10010
using namespace std;
int n, m, val[maxn];
int ans1, ans2;
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
scanf("%d", &val[i]);
val[i] <<= 1;
}
int a, b, c;
for(int i = 1; i <= m; i++){
scanf("%d%d%d", &a, &b, &c);
val[a] += c;
val[b] += c;
}
sort(val+1, val+n+1);
for(int i = n; i; i--){
if(i & 1) ans2 += val[i];
else ans1 += val[i];
}
printf("%d\n", (ans1 - ans2) >> 1);
return 0;
}