[TYVJ] 2054 四叶草魔杖[Nescafé29]

时间: 1000ms / 空间: 131072KiB / Java类名: Main

背景

陶醉在彩虹光芒笼罩的美景之中,探险队员们不知不觉已经穿过了七色虹,到达了目的地,面前出现了一座城堡和小溪田园,城堡前的木牌上写着“Poetic Island”。

“这一定就是另外两位护法的所在地了……我们快进去吧!”

探险队员们快步进入了城堡,城堡大厅的羊毛沙发上坐着两个人。

“你们是Nescafe的护法吧?”

“是的哦~ 我们就是圣剑护法rainbow和魔杖护法freda~ 你们来这里做什么呢~”

“我们是来拜访圣主和四位护法的……”

“可是圣主applepi已经前往超自然之界的学校(Preternatural Kingdom University,简称PKU)修炼魔法了,要想见到他,必须开启Nescafe之塔与超自然之界的通道。但是圣主规定,开启通道的方法不能告诉任何外人。我只能提示你们,开启通道的钥匙就与四位护法有关T_T”

探险队员环视四周,突然,其中一人的目光停留在了魔杖之上。“hoho~ 魔杖!传说中开启异时空通道的钥匙不就叫四叶草魔杖吗?四叶草有力量、信心、希望和幸运四片叶子,护法恰好有神刀、飞箭、圣剑、魔杖四位!aha~我找到答案了!”

“好吧,那我们就满足你们的愿望~”

描述

魔杖护法Freda融合了四件武器,于是魔杖顶端缓缓地生出了一棵四叶草,四片叶子幻发着淡淡的七色光。圣剑护法rainbow取出了一个圆盘,圆盘上镶嵌着$$N$$颗宝石,编号为$$0 \cdots N-1$$。第$$i$$颗宝石的能量是$$A_i$$。如果$$A_i>0$$,表示这颗宝石能量过高,需要把$$A_i$$的能量传给其它宝石;如果$$A_i<0$$,表示这颗宝石的能量过低,需要从其它宝石处获取$$-A_i$$的能量。保证$$\sum A_i =0$$。只有当所有宝石的能量均相同时,把四叶草魔杖插入圆盘中央,才能开启超自然之界的通道。

不过,只有$$M$$对宝石之间可以互相传递能量,其中第$$i$$对宝石之间无论传递多少能量,都要花费$$T_i$$的代价。探险队员们想知道,最少需要花费多少代价才能使所有宝石的能量都相同?

输入格式

第一行两个整数$$N$$、$$M$$。

第二行$$N$$个整数$$A_i$$。

接下来$$M$$行每行三个整数$$p_i,q_i,T_i$$,表示在编号为$$p_i$$和$$q_i$$的宝石之间传递能量需要花费$$T_i$$的代价。数据保证每对$$p_i$$、$$q_i$$最多出现一次。

输出格式

输出一个整数表示答案。无解输出 Impossible 。

测试样例

输入
3 3
50 -20 -30
0 1 10
1 2 20
0 2 100

输出

30

备注

对于 50% 的数据,$$2 \leq N \leq 8$$。

对于 100% 的数据,$$2 \leq N \leq 16$$,$$0 \leq M \leq \frac{N \times (N-1)}{2}$$,$$0\leq p_i,q_i<N$$,$$-1000 \leq A_i \leq 1000$$,$$ 0 \leq T_i \leq 1000$$,$$ \sum A_i=0$$。

思路

最小生成树

最小生成树累加边权并判断Impossible

代码

#include <bits/stdc++.h>
using namespace std;

int n,m;
int a[1005],fa[10005],num[1005];
struct node
{
    int u,v,val;
}e[10005];

int find_fa(int x)
{
    return (fa[x]==x)?x:fa[x]=find_fa(fa[x]);
}

bool cmp(node a,node b)
{
    return a.val<b.val;
}

int main()
{
    cin>>n>>m;

    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=m;i++)
        cin>>e[i].u>>e[i].v>>e[i].val,num[e[i].u+1]++,num[e[i].v+1]++;
    for(int i=1;i<=n;i++)
        if(num[i]==0 && a[i])
        {
            cout<<"Impossible"<<endl;
            return 0;
        }
    int ans=0,cnt=0;
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=n;i++)
        fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int a=find_fa(e[i].u);
        int b=find_fa(e[i].v);
        if(a!=b)
        {
            fa[a]=b;
            ans+=e[i].val;
            cnt++;
        }
        if(cnt==n-1) break;
    }
    cout<<ans;
}

results matching ""

    No results matching ""