POJ3013 Big Christmas Tree(最短路径树)
生活随笔
收集整理的這篇文章主要介紹了
POJ3013 Big Christmas Tree(最短路径树)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大概說給一張點和邊都有權的圖,現在要求其一棵以1結點為根的生成樹使樹的邊權和最小,樹邊權 = 對應的圖邊權 * 樹邊末端點為根的子樹所有結點對于圖頂點的點權和。
要求∑(邊權*子樹點權和),等價于求∑(點權*點到根路徑上的邊權和)。
而如果在圖中各個點到根都存在最短路,那么最短路的邊一定能構造出一棵生成樹。一個構造方法就是在進行最短路的松弛操作時記錄各點是從哪點轉移的,而各點的這個前驅是唯一的這就對應著各點的父結點。這就是最短路徑樹。
那么這一題直接求各個點到1點的最短路,最后乘一下加一下就OK了。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1LL<<60) 7 #define MAXN 55555 8 #define MAXM 55555*2 9 10 struct Edge{ 11 int v,w,next; 12 }edge[MAXM]; 13 int NE,head[MAXN]; 14 void addEdge(int u,int v,int w){ 15 edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u]; 16 head[u]=NE++; 17 } 18 19 long long d[MAXN]; 20 bool vis[MAXN]; 21 bool SPFA(int n){ 22 for(int i=1; i<=n; ++i){ 23 d[i]=INF; vis[i]=0; 24 } 25 d[1]=0; vis[1]=1; 26 queue<int> que; 27 que.push(1); 28 while(!que.empty()){ 29 int u=que.front(); que.pop(); 30 for(int i=head[u]; i!=-1; i=edge[i].next){ 31 int v=edge[i].v; 32 if(d[v]>d[u]+edge[i].w){ 33 d[v]=d[u]+edge[i].w; 34 if(!vis[v]){ 35 vis[v]=1; 36 que.push(v); 37 } 38 } 39 } 40 vis[u]=0; 41 } 42 for(int i=1; i<=n; ++i){ 43 if(d[i]==INF) return 0; 44 } 45 return 1; 46 } 47 48 int weight[MAXN]; 49 int main(){ 50 int t,n,m,a,b,c; 51 scanf("%d",&t); 52 while(t--){ 53 scanf("%d%d",&n,&m); 54 for(int i=1; i<=n; ++i){ 55 scanf("%d",weight+i); 56 } 57 NE=0; 58 memset(head,-1,sizeof(head)); 59 while(m--){ 60 scanf("%d%d%d",&a,&b,&c); 61 addEdge(a,b,c); 62 addEdge(b,a,c); 63 } 64 if(!SPFA(n)){ 65 puts("No Answer"); 66 continue; 67 } 68 long long ans=0; 69 for(int i=1; i<=n; ++i){ 70 ans+=d[i]*weight[i]; 71 } 72 printf("%lld\n",ans); 73 } 74 return 0; 75 }?
轉載于:https://www.cnblogs.com/WABoss/p/5475577.html
總結
以上是生活随笔為你收集整理的POJ3013 Big Christmas Tree(最短路径树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: KTH数据库
- 下一篇: TCP/IP详解学习笔记(5)-IP选路