POJ 3013 Big Christmas Tree (最短路 spfa)

来源:互联网 发布:javascript 控制height 编辑:程序博客网 时间:2024/05/18 01:36

题意:

t个样例,v个点,e条边。让你把所有的点都链接起来,并算出这个以1为根的树的重量等于多少。

思路:

这里写图片描述
对于这组样例:
7 7
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
题目中给出的规则是这样的:假设现在咱们要算2这个点的重量,那么我们就需要把2的所有子节点的权值加起来再乘以这条边的权值:(20+40+50+60)*3 。然后2这个点还有另外一条需要算的,同理得 40*2 。
仔细观察我们能发现:对于每个点来说,都是自己的权值乘上自己到1的路径。
由于题目让求最小重量,所以我们只需要求得1到所有点的最短路径即可。

坑点:

1,注意最大值的设立,(1 << 16) * 50010 应该就足够了。
2,慎用vector
3,注意当点的数量为0或1的时候的特判。输出0
4,注意int会爆。

AC代码:

#include <iostream>#include <cstdio>#include <string.h>#include <queue>typedef long long int lli;using namespace std;const lli INF = (1LL<<16)*50010;lli dis[50010];bool vis[50010];// 是否在队列里int cntn[50010];// cnt of nodeint a[50010];int head[50010];int cnte;struct edge{    int to;    int v;    int next;}edg[200100];void addedge(int x,int y,int v){    edg[++cnte].to = y;    edg[cnte].v = v;    edg[cnte].next = head[x];    head[x] = cnte;}bool spfa(int n){    queue<int> q;    q.push(1);    dis[1] = 0;    cntn[1]++;    int po;    while(!q.empty()){        po = q.front();        q.pop();        vis[po] = false;        for(int i = head[po]; i != -1;i = edg[i].next){            if(dis[edg[i].to] > dis[po] + edg[i].v){                dis[edg[i].to] = dis[po] + edg[i].v;                if(vis[edg[i].to] == false){                    q.push(edg[i].to);                    vis[edg[i].to] = true;                    cntn[edg[i].to]++;                    if(cntn[edg[i].to] >= n) return false;                }            }        }    }    return true;}int main(){    int t;    cin>>t;    int n,m;    int x,y,z;    while(t--){        memset(vis,false,sizeof(vis));        memset(cntn,0,sizeof(cntn));        memset(head,-1,sizeof(head));        cnte = 0;        scanf("%d%d",&n,&m);        for(int i = 1;i <= n;i++){            scanf("%d",a+i);            dis[i] = INF;        }        for(int i = 1;i <= m;i++){            scanf("%d%d%d",&x,&y,&z);            addedge(x,y,z);            addedge(y,x,z);        }        if(n == 0 || n == 1){            printf("0\n");            continue;        }        if(spfa(n)){            lli ans = 0;            for(int i = 2;i <= n;i++){                if(dis[i] == INF){                    ans = -1;                    break;                }                ans += dis[i]*a[i];            }            if(ans != -1)                printf("%lld\n",ans);            else                puts("No Answer");        }        else            puts("No Answer");    }    return 0;}
0 0
原创粉丝点击