题意: 有N个点,M条边。 点有权值, 边有权值。 Alice, Bob 分别选点。 如果一条边的两个顶点被同一个人选了, 那么能获得该权值。问 Alice - Bob?
思路: 贪心。
对于一条边来说, 如果拿了一个点, 说明已经拿了该边的一半权值。
如果某边的两个的顶点分别是不同的人。 那么差值还是不变的。
如果某边的两个顶点分别是同一个人。 那么和值也不变。
所以我们可以把一个边分解到两个顶点上。
然后依次Alice 取最大,Bob 取次大。 因为 他们都是绝顶聪明的。
当时也想过,但是觉着不可能这么简单,一直没敢写,结果。。它就是这么简单~- -。。。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <stdlib.h> 6 #include <vector> 7 #include <queue> 8 #define loop(s,i,n) for(i = s;i < n;i++) 9 #define cl(a,b) memset(a,b,sizeof(a)) 10 using namespace std; 11 double a[100050]; 12 int n,m; 13 int cmp(const double a,const double b) 14 { 15 return a > b; 16 } 17 int main() 18 { 19 while(~scanf("%d %d",&n,&m)) 20 { 21 22 int j,i; 23 for(i = 1; i <= n; i++) 24 scanf("%lf",&a[i]); 25 26 for(i = 1; i <= m; i++) 27 { 28 int u,v; 29 double w; 30 scanf("%d %d %lf",&u,&v,&w); 31 a[u] += w/2.0; 32 a[v] += w/2.0; 33 } 34 35 sort(a+1,a+1+n,cmp); 36 37 double s1,s2; 38 s1 = s2 = 0; 39 for(i = 1; i <= n; i++) 40 { 41 if(i%2 == 1) 42 s1 += a[i]; 43 else 44 s2 += a[i]; 45 } 46 47 printf("%.0lf ",(s1-s2)); 48 } 49 return 0; 50 }