SDNU 1258.Problem F. The Avengers kruskal

1258.Problem F. The Avengers
Time Limit: 1000 MS    Memory Limit: 32768 KB

Description
When global security is threatened by Loki, Nick Fury and his team will need a team to protect the world from disaster. So he created S.H.I.E.L.D, an international peace keeping agency. He is director of S.H.I.E.L.D. And then he find some super human to organize The Avengers, including Tony Stark a.k.a. the Iron Man, Steve Rogers, a.k.a. Captain America, Bruce Banner, a.k.a. The Hulk, Thor; Natasha Romanoff, a.k.a. Black Widow and so on. After beating Loki, they become a real team -- The Avengers!


Though Loki was defeated, Nick Fury think this thing is just a start, not the end. But these superhero’s residences are different, like Thor. So if the world need The Avengers, they can’t assemble quickly. Stack think he can build some way which is The Avengers’ exclusive. Thor don’t agree his idea because his hometown is far away from the earth. Stack can’t build way in the universe. Thor shows that he will send his soldiers to build some Transmission devices like Bifrost. Stack insist that the freeway is cheaper and more convenient to build, though he is not mind the cost.


Now they have an argument. Rogers calm them and let Stack and Thor calculate the cost by their idea, and he will find out the best solution. Because their conditions are different, so maybe sometimes they won’t cost anything but earn something. For example, when Stack build his way to Wakanda, T'Challa not only don’t use Stack’s material, but also give some Vibranium for Stack. By Stack’s calculate, he write all the way he can build and these way’s cost.(If Stack earn, he will write a minus.) As for Thor, Bifrost is a Transmission device, so if one city build a Bifrost, this city can transmit to another city which have built a Bifrost. So he just write the cost in every residences. But Bifrost’s material only Thor have in this world. So Thor can’t earn anything from other heroes.And because of some zone is special, these zone can’t use Bifrost.(If Thor can’t build Bifrost, he will write “-1”)


Just when Rogers plan to calculate the best solution. He receive a bad news -- HYDRA is coming. So he must set off now! He give you this task, please give him a best solution. Believe yourself! You can be a superhero, you can be an avenger!


The Avengers, Assemble! Please quickly!


Input
Input contains multiple test cases.


The first line contains two integer numbers N and M (1 <= N <= 10000, 1 <= M <= 100000). N means the number of superhero(their residences are different with each other).Their residences are numbered from 1 to N. M means the number of the way which Stack can build.


Each of the following M lines contains three integer numbers A, B and C (1 <= A, B <= N, -1000 <= C <= 1000). It shows that there can build a way from A residence to B residence with cost C.


The last line consists of N integer numbers w_i(-1 <= w_i <= 1000).It means the Bifrost built in i-th city with cost w_i.


(I promise that all superheroes must have a way can assemble.)


Output
A single line consisting of a single integer number -- the Minimum cost.(If there is a solution can earn and solve this problem, output a minus means the gains.)


Sample Input
6 10
1 2 3
2 1 1
5 6 10
1 5 8
2 5 6
1 3 7
3 4 -3
2 4 9
6 4 12
2 3 2
-1 -1 10 20 1 1
Sample Output
8
Hint

For sample, Stack build the 2-th, 5-th, 7-th, 10-th way, and Thor build Bifrost in 5-th, 6-th city.

 

    为了锻炼一下新生的耐心,我特地出了一道英文很长的题,结果没一个人做......伤心= =刚看完黑豹,所以干脆顺便以复联为背景出了这道,这么有趣的题面都没人读的么→ _→ (绝对不是因为我出的题太难,一定是这样emmm!)

    这道题其实源于蓝桥杯的一道题,因为我看新生赛没有图论的题所以打算出个图论,但是上次出最小生成树的题发现为了保证题面没问题不能直接跑随机数,然后就特别麻烦......所以为了省事我直接“偷”的蓝桥杯的数据emmm

    好吧下面说正事,题面意思是说复仇者们需要集合,但是他们住的地方都不一样,所以斯塔克打算在两个复仇者住的地方之间建一个复仇者专用的路。但是托尔认为有些在宇宙中的人无法建路,但是他可以建彩虹桥来实现传送(任意两个建了彩虹桥的地方都可以互通)。第一行两个数,N表示有几个复仇者,M表示斯塔克总共可以建几条路。之后M行,每行3个数字,前两个数字表示在这两个地方之间建路,最后一个数字表示建路所需要的花费(负数表示不仅不需要花费还可以赚钱),最后一行表示在这N个地方建彩虹桥所需的花费(-1表示不能建彩虹桥),问最佳的方案的花费是多少。(如果最后反而赚钱了就输出负数)

    那么如何处理这两条路,其实可以假设出一个点0作为彩虹桥的中间点,然后让所有的彩虹桥的点都连到这个0点上,就构成了一个完整的图。然后要跑两遍kruskal,一遍包括彩虹桥,另一遍不包括彩虹桥,然后取最小值。因为如果不这样做的话,可能不包括彩虹桥我们就可以得到最佳方案,但因为多加了0这个点,所以跑完kruskal可能会把这个点也默认加进去,然后导致最后的结果大于我们的最佳方案。

    最后还要注意一点,即使已经连接完所有点,但是如果有能赚钱的路还没建,那么我们也必须要加上的,虽然多建了路但是既然能赚不建白不建对吧→ _→

    (其实感觉这题挺有意思的很想看你们新生做做,晚点再写题解......可惜比赛都没人做,我觉得现在更没人做......我还是写出来吧)

    下面AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct Edge{
    int from,to;
    int w;
};

Edge e[200005];
int father[200005];
int n,m;

bool cmp(Edge a,Edge b)
{
    return a.w<b.w;
}

void init()
{
    int i;
    for(i=0;i<=n;i++)
        father[i]=i;
}

int fin(int x)
{
    int temp;
    temp=x;
    while(x!=father[x])
    {
        x=father[x];
    }
    int root=x;
    x=temp;
    while(x!=father[x])
    {
        temp=father[x];
        father[x]=root;
        x=temp;
    }
    return root;
}

void merg(int a,int b)
{
    int x,y;
    x=fin(a);
    y=fin(b);
    if(x<y)
        father[y]=x;
    else
        father[x]=y;
}

int kruskal(int n,int m)
{
    int i;
    int sum=0;
    int num=0;
    int from,to;
    init();
    sort(e,e+m,cmp);
    for(i=0;i<m;i++)
    {
        from=fin(e[i].from);
        to=fin(e[i].to);
        if(from!=to)
        {
            merg(from,to);
            sum+=e[i].w;
            num++;
        }
        else if(e[i].w<0)
            sum+=e[i].w;
    }
    if(num!=n-1)
        return -1;
    else
        return sum;
}

int main()
{
    int i,j;
    int a,b,c;
    int t;
    int cou;
    int ans;
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        cou=0;
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            e[i].from=a;
            e[i].to=b;
            e[i].w=c;
        }
        for(i=1;i<=n;i++)
        {
            scanf("%d",&t);
            if(t!=-1)
            {
                e[m+cou].from=0;
                e[m+cou].to=i;
                e[m+cou].w=t;
                cou++;
            }
        }
        ans=kruskal(n,m);
        if(ans!=-1)
        {
            ans=min(ans,kruskal(n+1,m+cou));
        }
        else
            ans=kruskal(n+1,m+cou);
        cout<<ans<<endl;
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值