POJ-3013 Big Christmas Tree 最短路[推荐]

  题目链接:http://poj.org/problem?id=3013

  题目大意是给你一颗树,树的边权值是当前边的所有儿子节点的权值之和*树边的固定花费,求整棵树的最小的花费。可以看出,每个儿子节点他的所有的祖先都有一个花费贡献值,要使得总共的花费最小,那么就要使他到根节点的固定花费最小,就是一个最短路的模型了。题目要注意几点:1,图是无向图 2,数据超int 3,注意n=0和n=1的情况。

 1 //STATUS:C++_AC_594MS_4312KB
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<string>
 8 #include<algorithm>
 9 #include<vector>
10 #include<queue>
11 #include<stack>
12 using namespace std;
13 #define LL __int64
14 #define pii pair<LL,int>
15 #define Max(a,b) ((a)>(b)?(a):(b))
16 #define Min(a,b) ((a)<(b)?(a):(b))
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define lson l,mid,rt<<1
19 #define rson mid+1,r,rt<<1|1
20 const int N=50010,M=1000000,INF=0x3f3f3f3f,MOD=1999997;
21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL;
22 const double DNF=100000000;
23 
24 struct Edge{
25     int u,v,w;
26 }e[2*N];
27 int first[N],next[2*N],p[N],w[N];
28 int T,n,m,mt;
29 LL ans,d[N];
30 
31 void adde(int a,int b,int c)
32 {
33     e[mt].u=a,e[mt].v=b;e[mt].w=c;
34     next[mt]=first[a],first[a]=mt++;
35     e[mt].u=b,e[mt].v=a;e[mt].w=c;
36     next[mt]=first[b],first[b]=mt++;
37 }
38 
39 int dijkstra(int s)
40 {
41     int i,u,cou=0;
42     pii t;
43     priority_queue<pii,vector<pii>,greater<pii> > q;
44     mem(d,0x3f);d[s]=0;
45     q.push(make_pair(d[s],s));
46     while(!q.empty()){
47         t=q.top();q.pop();
48         u=t.second;
49         if(t.first!=d[u])continue;
50         cou++;
51         for(i=first[u];i!=-1;i=next[i]){
52             if(d[u]+e[i].w<d[e[i].v]){
53                 d[e[i].v]=d[u]+e[i].w;
54                 p[e[i].v]=i;
55                 q.push(make_pair(d[e[i].v],e[i].v));
56             }
57         }
58     }
59     return cou;
60 }
61 
62 LL dfs(int u)
63 {
64     int i;
65     LL sum=w[u],t;
66     for(i=first[u];i!=-1;i=next[i]){
67         if(p[e[i].v]==i){
68             sum+=t=dfs(e[i].v);
69             ans+=e[i].w*t;
70         }
71     }
72     return sum;
73 }
74 
75 int main()
76 {
77  //   freopen("in.txt","r",stdin);
78     int i,a,b,c;
79     scanf("%d",&T);
80     while(T--)
81     {
82         ans=mt=0;
83         mem(first,-1);
84         mem(p,-1);
85         scanf("%d%d",&n,&m);
86         for(i=1;i<=n;i++)
87             scanf("%d",w+i);
88         for(i=0;i<m;i++){
89             scanf("%d%d%d",&a,&b,&c);
90             adde(a,b,c);
91         }
92 
93         if(dijkstra(1)==n || n==0){dfs(1);printf("%I64d\n",ans);}
94         else printf("No Answer\n");
95     }
96     return 0;
97 }

 

posted @ 2013-01-22 02:18  zhsl  阅读(324)  评论(0编辑  收藏  举报