poj3013 Big Christmas Tree --- 最短路

我都不好意思在标题上写这是最短路

这题挺有意思,关键在于把题目所求的量转换为最短路问题。

题意:

给一个无向图,每个结点有权值p[i],每条边有权值w[i]

求使这颗树所有顶点与根节点1联通的最小花费,

最小花费=∑w[i]×∑p[i]

第一个∑是所有边,第二个∑是该边下所有结点的权值和

思路:

通过推导可以发现,对于每个结点,它被算入的花费为 p[i]*d[i],

d[i]为该结点到根结点的距离。

于是豁然开朗了吧。。水题一道

唯一的坑点是要int64,而且inf要足够大

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
const ll inf=1ll<<60;//坑死!这题inf必须足够大
#define N 50010
#define M 100010

struct node
{
    int v,next;
    ll w;
}e[M];
int vis[N],n,m,head[N],h;
ll d[N],p[N];

void addedge(int a,int b,ll c)
{
    e[h].v=b;
    e[h].w=c;
    e[h].next=head[a];
    head[a]=h++;
}

int spfa(int st)
{
    memset(vis,0,sizeof vis);
    for(int i=0;i<=n;i++)
        d[i]=inf;
    d[st]=0;
    vis[st]=1;
    queue<int> q;
    q.push(st);
    int x,i,v;
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        vis[x]=0;
        for(i=head[x];i!=-1;i=e[i].next)
        {
            v=e[i].v;
            if(d[v]>d[x]+e[i].w)
            {
                d[v]=d[x]+e[i].w;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}

void init()
{
    memset(head,-1,sizeof head);
    h=0;
}

int main()
{
    int t,a,b,i;
    ll ans,c;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            cin>>p[i];
        while(m--)
        {
            scanf("%d%d",&a,&b);
            cin>>c;
            addedge(a,b,c);
            addedge(b,a,c);
        }
        spfa(1);
        ans=0;
        int flag=1;
        for(i=2;i<=n;i++)
        {
            if(d[i]==inf)
            {
                flag=0;
                break;
            }
            ans+=(d[i]*p[i]);
        }
        if(!flag)  printf("No Answer\n");
        else cout<<ans<<endl;
    }
    return 0;
}

poj3013 Big Christmas Tree --- 最短路,布布扣,bubuko.com

时间: 2024-08-10 23:10:54

poj3013 Big Christmas Tree --- 最短路的相关文章

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA)

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n,树根为编号1,选择一些边,使得所有节点构成一棵树,选择边的代价是(子孙的点的重量)×(这条边的价值).求代价最小多少. 分析: 单看每个点被计算过的代价,很明显就是从根到节点的边的价值.所以这是个简单的单源最短路问题. 不过坑点还是很多的. 点的数量高达5w个,用矩阵存不行,只能用边存. 还有路径和结

POJ3013 Big Christmas Tree[转换 最短路]

Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 23387   Accepted: 5063 Description Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of t

POJ_3013_Big Christmas Tree(最短路)

Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 21413   Accepted: 4635 Description Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of t

POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n.树根为编号1,选择一些边.使得全部节点构成一棵树.选择边的代价是(子孙的点的重量)×(这条边的价值). 求代价最小多少. 分析: 单看每一个点被计算过的代价,非常明显就是从根到节点的边的价值.所以这是个简单的单源最短路问题. 只是坑点还是非常多的. 点的数量高达5w个,用矩阵存不行.仅仅能用边存. 还

poj 3013 Big Christmas Tree (dij+优先队列优化 求最短路)

模板 题意:给你一个图,1总是为根,每个边有单位价值,每个点有权重. 每条边的价值 = sum(后继节点权重)*边的单位价值. 求树的最小价值,即构成一棵树的n-1条边的最小价值. 算法: 1.因为每个边的价值都要乘以后来访问的节点的权重,而走到后来访问的点必经过这条边. 实际上总价值就是  到每个点的最短路径*这个点的权重. 2.但是这个题 数据量真的太大了,50000个点,50000条边. 写普通的dij算法tle. 必须加优先队列优化- - 据说spfa也能过,但是spfa算法不稳定- -

POJ 3013 Big Christmas Tree【最短路变形,DIjkstra堆优化+spfa算法】

Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 23064   Accepted: 4987 Description Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of t

POJ Big Christmas Tree(基础最短路)

Big Christmas Tree 题目分析: 叫你构造一颗圣诞树,使得 (sum of weights of all descendant nodes) × (unit price of the edge)尽量的小.转换后就是求根节点到每个节点的距离最短,也就是最短路.生成树可能会超时,我没试过.然后,求解最短路要用优化的解法不然会超时.最后的答案就是:sum = w[1] * dist[1] + w[2] * dist[2] + ..... w[n] * dist[n].可以自己推推样例就

poj 3013 Big Christmas Tree

Big Christmas Tree 题意:输入v个节点和e条边(0 ≤ v, e ≤ 50000) 的图,第二行输入每个节点的权值,之后e行输入每条边的端点和权值: 问是否能找出一棵树,使得树中的边权乘以该边下面的子孙节点权值之和的sigma总和最小:(树以1为根节点) Sample Input 1 200 10 20 30 40 50 60 1 2 1 2 3 3 2 4 2 3 5 4 3 7 2 3 6 3 1 5 9 (删掉) Sample Output 1210 分析:如果计算最小乘

POJ Big Christmas Tree(最短的基础)

Big Christmas Tree 题目分析: 叫你构造一颗圣诞树,使得 (sum of weights of all descendant nodes) × (unit price of the edge)尽量的小.转换后就是求根节点到每一个节点的距离最短,也就是最短路. 生成树可能会超时.我没试过.然后,求解最短路要用优化的解法不然会超时.最后的答案就是:sum = w[1] * dist[1] + w[2] * dist[2] + ..... w[n] * dist[n].能够自己推推例