Cheering up the Cows,2008nov,usaco

来源:互联网 发布:手机python编程软件 编辑:程序博客网 时间:2024/05/16 14:46

那道题搞一搞会发现在选好的n-1 条边上,每条边走两次,还需要花掉两个端点需要的时间,才能回到原点。那么我们不妨把每个边权设成路长*2+两个端点的时间,这样建最小生成树就可以了。还有,回到出发点还要加上出发点的值。

#include<stdio.h>#include<algorithm>using namespace std;struct node{    int from;    int to;    int len;}edge[2000000];int cmp(node a,node b){    return a.len<b.len?1:0;}int n,m;int val[2000000];int f[2000000];int ans;void in(){    for(int i=1;i<=n;i++)    {        f[i]=i;    }}int find(int x){    if(f[x]==x)    {        return x;    }else    {        f[x]=find(f[x]);        return f[x];    }}void kru(){    int cnt=0;    for(int i=1;i<=m;i++)    {        int fx=find(edge[i].from);        int fy=find(edge[i].to);        if(fx!=fy)        {            cnt++;            f[fy]=fx;            ans+=edge[i].len;            if(cnt==n-1)            {                return ;            }                     }    }}int main(){         scanf("%d %d",&n,&m);    int min=9999999;    for(int i=1;i<=n;i++)    {        scanf("%d",&val[i]);        if(val[i]<min)        {            min=val[i];        }    }    for(int i=1;i<=m;i++)    {        int v;        scanf("%d %d %d",&edge[i].from,&edge[i].to,&v);        edge[i].len=val[edge[i].from]+val[edge[i].to]+v*2;    }    sort(edge+1,edge+1+m,cmp);    in();    kru();    printf("%d",ans+min);}


0 0
原创粉丝点击