1. 程式人生 > >【bzoj2563】 阿狸和桃子的遊戲

【bzoj2563】 阿狸和桃子的遊戲

題目

非常妙的題目,一看到就以為是一道博弈,之後就不會做了

正解非常巧妙,由於我們只需要求出最後兩個人得分的差值,所以對於每一條邊我們將其的權值拆成兩邊,分給其連線的兩個點

如果這兩個點被同一個人選擇,那麼這條邊的邊權就會加到最後這個人的總得分裡去,如果被兩個人分別選擇,那麼兩個人每個人都獲得了權值的一半,對最後的差值沒有什麼影響

所以拆分邊權之後排序就好了,非常顯然每個人都要選擇點權最大的點

程式碼

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define re register
#define maxn 100005
inline int read()
{
    char c=getchar();
    int x=0,r=1;
    while(c<'0'||c>'9')
    {
        if(c=='-') r=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
        x=(x<<3)+(x<<1)+c-48,c=getchar();
    return x*r;
}
int n,m,a[maxn];
inline int cmp(int A,int B)
{
    return A>B;
}
int main()
{
    n=read(),m=read();
    for(re int i=1;i<=n;i++) a[i]=read()*2;
    int x,y,z;
    for(re int i=1;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        a[x]+=z,a[y]+=z;
    }
    std::sort(a+1,a+n+1,cmp);
    int ans=0;
    for(re int i=1;i<=n;i++)
    if(i&1) ans+=a[i];
        else ans-=a[i];
    std::cout<<(ans>>1);
    return 0;
}