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 }