最短路变形 poj3013

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

题意:给出n个点,m个边。给出每个点的权值,每个边的权值。求建立一棵树,root=1,求这棵树的最小费用,费用=树上每条边*子树中各顶点的权值。

思路:root的权值是没用的,而其余节点是必须用的,每条边*子树中各定点的权值=各个点*点到根的最短路,于是转化成了root到各个点的最短路。

610ms~

View Code
 1 #include <queue>
 2 #include <stdio.h>
 3 #include <iostream>
 4 using namespace std;
 5 const long long INF=10000000000;
 6 const int M=50005;
 7 int n,m,edgeNum;
 8 long long dis[M];
 9 int head[M];
10 int visit[M];
11 int weight[M];
12 struct Edge{
13     int w;
14     int to;
15     int next;
16 }edge[M*2];
17 struct Node{
18     int u;
19     int dis;
20     bool operator < (const Node &a) const{
21         return dis>a.dis;
22     }
23 };
24 void init(){
25     int i;
26     edgeNum=0;
27     for(i=0;i<M;i++){
28         visit[i]=0;
29         head[i]=-1;
30         dis[i]=INF;
31     }
32 }
33 void addEdge(int a,int b,int c){
34     edge[edgeNum].w=c;
35     edge[edgeNum].to=b;
36     edge[edgeNum].next=head[a];
37     head[a]=edgeNum++;
38 }
39 void Dij(int u){
40     int i,v;
41     Node temp,now;
42     priority_queue<Node> q;
43     temp.dis=0;
44     temp.u=u;
45     dis[u]=0;
46     q.push(temp);
47     while(!q.empty()){
48         temp=q.top();
49         q.pop();
50         if(visit[temp.u]) continue;
51         visit[temp.u]=1;
52         for(i=head[temp.u];i!=-1;i=edge[i].next){
53             v=edge[i].to;
54             if(!visit[v]&&dis[v]>dis[temp.u]+edge[i].w){
55                 dis[v]=dis[temp.u]+edge[i].w;
56                 now.dis=dis[v];
57                 now.u=v;
58                 q.push(now);
59             }
60         }
61     }
62     return ;
63 }
64 int main(){
65     int T,a,b,c,i;
66     scanf("%d",&T);
67     while(T--){
68         scanf("%d%d",&n,&m);
69         init();
70         for(i=0;i<n;i++)
71             scanf("%d",&weight[i]);
72         for(i=0;i<m;i++){
73             scanf("%d%d%d",&a,&b,&c);
74             a--;b--;
75             addEdge(a,b,c);
76             addEdge(b,a,c);
77         }
78         Dij(0);
79         long long res=0;
80         for(i=0;i<n;i++){
81             if(dis[i]==INF) break;
82             res+=dis[i]*weight[i];
83         }
84         if(i==n) printf("%lld\n",res);
85         else puts("No Answer");
86     }
87     return 0;
88 }

注意:long long

posted @ 2013-02-02 23:35  _sunshine  阅读(989)  评论(0编辑  收藏  举报