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 }

 

你可能感兴趣的:(tree)