HDU4647:Another Graph Game(贪心)

Problem Description

Alice and Bob are playing a game on an undirected graph with n (n is even) nodes and m edges. Every node i has its own weight Wv, and every edge e has its own weight We.

They take turns to do the following operations. During each operation, either Alice or Bob can take one of the nodes from the graph that haven‘t been taken before. Alice goes first.

The scoring rule is: One person can get the bonus attached to a node if he/she have choosen that node before. One person can get the bonus attached to a edge if he/she have choosen both node that induced by the edge before.

You can assume Alice and Bob are intelligent enough and do operations optimally, both Alice and Bob‘s target is maximize their score - opponent‘s.

What is the final result for Alice - Bob.

Input

Muilticases. The first line have two numbers n and m.(1 <= n <= 105, 0<=m<=105) The next line have n numbers from W1 to Wn which Wi is the weight of node i.(|Wi|<=109)

The next m lines, each line have three numbers u, v, w,(1≤u,v≤n,|w|<=109) the first 2 numbers is the two nodes on the edge, and the last one is the weight on the edge.

Output

One line the final result.

Sample Input

4 0
9 8 6 5

Sample Output

2

题意:

对于一个图,两个人轮流取点,谁取得那个点则获得那个点的价值,而一个人如果取得同一条边的两点,则同时也会获得这条边的价值,两人都按最优方案去取,最后输出价值之差

思路:

只要将边分半给两个点即可,如果两点同时在一个人身上,那么边的价值也会加上去,如果两点在两个人身上,那么边的价值会被减去
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;

#define ls 2*i
#define rs 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 100005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8
#define rank rank1
const int mod = 10007;

int n,m;
double a[N];

int main()
{
    int i,j,k,x,y;
    double w;
    while(~scanf("%d%d",&n,&m))
    {
        for(i = 1; i<=n; i++)
            scanf("%lf",&a[i]);
        for(i = 1; i<=m; i++)
        {
            scanf("%d%d%lf",&x,&y,&w);
            w=w/2;
            a[x]+=w;
            a[y]+=w;
        }
        sort(a+1,a+1+n);
        double sum1=0,sum2=0;
        for(i = 1; i<=n; i++)
        {
            if(i%2==0)
                sum1+=a[i];
            else
                sum2+=a[i];
        }
        printf("%.0f\n",sum1-sum2);
    }

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-26 08:35:08

HDU4647:Another Graph Game(贪心)的相关文章

HDU-4647 Another Graph Game 贪心

将边权拆成两半加到它所关联的两个点的点权中即可.因为当两个人分别选择不同的点时,这一权值将互相抵消.然后排序从最优开始取. #include <iostream> #include <cstdio> #include <cmath> #include <queue> #include <algorithm> #include <iomanip> #include <cstring> #include <vector&

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

CF459E Pashmak and Graph【贪心+dp】

题目:CF459E Pashmak and Graph 题意:给出n个点,m条边的图,然后让你每次只能向权值更大边走,求最大的边数.可以走多次 分析:由于点比较多,我们可以先对权值从小到大排序,然后从小的开始,更新它的到的节点的值为前一个节点值+1,但是还会出现权值相等成环的情况,所以我们可以对相等的先不更新,保存起来,等相等的结束了再更新. 代码: #include<cstdio> #include<algorithm> using namespace std; const in

uva 10720 Graph Construction(贪心)

这道题目其实挺简单的,uva上通过率却很低,今天晚上的第二道题,什么时候一个晚上我能做4道中等难度的题目 我就满意了... 思路:本来我是想着排序后然后遍历数组,将当前i的后面a[i]个值一次减一,然后继续遍历继续重复这样做,里面 包含着条件,如果有数变成负数就不成立,或者后面的点小于当前的度数也不成立,然后就TLE了,这个方法是错误 的,因为当序列为 4 4 3 3 2 2的时候最后一个2就会比前面变成1的数字大,需要重新排序的...我是稍微瞄 了一眼别人提交的代码才想起来的,每次处理最大数字

2014-2015 CT S02E10 C题 Coin Graph 构造+贪心

题意:给定一个数s,构造一个无向图,使得任意两点的最短路径和为s. 思路:二分找到n,满足n×(n-1)/2<=s,且n尽可能大.这样的图,相当于n个点每两个点都连一条边.窝们考虑这样一种构造方法, 假设现在有n个点,我们按照逆时针方向(顺时针也行)排序编号,那么我们间隔删去不相邻点的的边,比如5个点,我们删去 1--3,1--4,...,1--n-2,1---n-1,保留2,删3--5,3--6,...3--n-2,3----n-1,保留4,删5--7,5--8,...,5--n-1.这样可以

hdu 6090 Rikka with Graph

Rikka with Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 425    Accepted Submission(s): 270 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation,

Contig|scaffold|N50|L50|NG50|贪心算法|de bruiji graph|

生物信息学 Contig是reads拼成的连续的DNA片段,连续表达一个gene.通过双端测序的contig可确定contig之间的关系得到scaffold,Scaffold是reads拼成的有gap的DNA片段.理想情况下,一条染色体用同一个scaffold的表达.整个genome存在很多零碎片段,可舍弃.因为duplication产生很多overlap. N50,L50和NG50是评价genome assembly的quality的标准,评价长度时使用N50,N50是一个contig的长度.

Gym - 100801G: Graph (贪心+set+拓扑)(好题)

题意:给定一个N点M边的有向图,叫你加最多K条边,使得最小拓扑序最大. 思路:不是那么简单的题.  参照了别人的代码,最后想通了. 贪心原则: 用两个单调队列维护, 第一个序列S1单增, 表示当前入度为0的点 ; 第二个序列S2单减,表示需要加边的点. 如果S1的最大值大于S2的最大值,则对其加边. #include<bits/stdc++.h> using namespace std; const int maxn=100010; priority_queue<int>p; pr

ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (贪心)

分析:贪心地删边后检查每个点的度即可,这也是正确的做法? #include <bits/stdc++.h> using namespace std; const int MAXN = 1e4+5; struct Edge{ int u,v,next; }edges[MAXN<<2]; int head[MAXN],tot; int deg[MAXN]; void init() { memset(head,-1,sizeof(head)); tot =0 ; memset(deg,0