阿狸和桃子的游戏

这题用到了巧妙的转化,还有贪心 (我现在缺的就是思维,还有代码能力...说是缺思维,其实就是缺,我自己打了堆来取...)

(1) 考虑每一个点

选了桃子与阿狸的差距+w,不选-w

(2) 考虑每一条边

一个端点不选差距-c

选了一个端点 0

两个都选差距+c

那我们一开始假设都没选

然后桃子每次选最大就行了

 

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#define ll long long
#define dd double
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
inline int read()
{
    char q=getchar();int ans=0,flag=1;
    while(q<'0'||q>'9'){if(q=='-')flag=-1;q=getchar();}
    while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
    return ans*flag;
}
const int N=100006;
struct BIIANANANA__
{
    int v,next,w;
}a1[N*3];
int first[N*3],e;
void addbian(int u,int v,int w)
{
    a1[e].v=v;
    a1[e].w=w;
    a1[e].next=first[u];
    first[u]=e++;
}

bool cmp(int a,int b)
{
    return a>b;
}

int n,m;
int w[N];
int sum;

int work()
{
    for(int i=1;i<=n;++i)
    {
        w[i]*=2;
        for(int j=first[i];j!=-1;j=a1[j].next)
            w[i]+=a1[j].w;
    }
    sort(w+1,w+1+n,cmp);
    for(int i=1;i<=n;++i)
    {
        if(i&1)
            sum+=w[i];
        //else
        //    sum+=w[i];
    }
    return sum;
}

int main(){

    //freopen("in.in","r",stdin);

    mem(first,-1);

    n=read();m=read();
    for(int i=1;i<=n;++i)
    {
        w[i]=read();
        sum-=w[i];
    }
    int tin1,tin2,tin3;
    for(int i=1;i<=m;++i)
    {
        tin1=read();tin2=read();tin3=read();
        addbian(tin1,tin2,tin3);
        addbian(tin2,tin1,tin3);
        sum-=tin3;
    }
    cout<<work();
}
A

 

 

 

posted @ 2017-10-11 17:39  A_LEAF  阅读(155)  评论(0编辑  收藏  举报