POJ 3013 dijkstra+优先队列

Big Christmas Tree

Time Limit: 3000MS   Memory Limit: 131072K
Total Submissions: 20918   Accepted: 4523

Description

Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of the tree is shown in right picture.

The tree can be represented as a collection of numbered nodes and some edges. The nodes are numbered 1 through n. The root is always numbered 1. Every node in the tree has its weight. The weights can be different from each other. Also the shape of every available edge between two nodes is different, so the unit price of each edge is different. Because of a technical difficulty, price of an edge will be (sum of weights of all descendant nodes) × (unit price of the edge).

Suby wants to minimize the cost of whole tree among all possible choices. Also he wants to use all nodes because he wants a large tree. So he decided to ask you for helping solve this task by find the minimum cost.

Input

The input consists of T test cases. The number of test cases T is given in the first line of the input file. Each test case consists of several lines. Two numbers ve (0 ≤ ve ≤ 50000) are given in the first line of each test case. On the next line, v positive integers wi indicating the weights of v nodes are given in one line. On the following e lines, each line contain three positive integers abc indicating the edge which is able to connect two nodes a and b, and unit price c.

All numbers in input are less than 216.

Output

For each test case, output an integer indicating the minimum possible cost for the tree in one line. If there is no way to build a Christmas tree, print “No Answer” in one line.

Sample Input

2
2 1
1 1
1 2 15
7 7
200 10 20 30 40 50 60
1 2 1
2 3 3
2 4 2
3 5 4
3 7 2
3 6 3
1 5 9

Sample Output

15
1210

题目意思:给一棵结点数目为n,边数为m的树,每个结点都有一个权值,每个边也有一个权值,咱们需要减一些树枝使得树的价值最小,剪枝时不能去掉任何结点但是可以去掉边。树的价值为每个结点的价值*该结点到树根1的长度之和。若给的数据没法构造树输出No Answer,否则输出最小价值。

思路:很明显,若求树的最小值则需要求每个结点到根的最短路径,那么就需要dijkstra了,但是给的数据量太大,所以用优先队列优化一下就行了。

代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8
 9 const long long inf=(long long)(1<<16)*50005;
10 #define N 50005
11
12
13 struct mem{
14     int y, w;
15 };
16 struct node{
17     long long d;
18     int e;
19     bool operator<(const node a)const{
20         return a.d<d;
21     }
22 };
23
24
25 long long dis[N];
26 int visited[N];
27 vector<mem>ve[N];
28 int w[N];
29 int n, m;
30
31 void dijkstra(){
32     int i, j;
33     priority_queue<node>Q;
34     int u, v;
35     node p, pp;
36     mem q;
37     for(i=0;i<=n;i++) dis[i]=inf;
38     memset(visited,0,sizeof(visited));
39     dis[1]=0;
40     p.d=0;p.e=1;
41     Q.push(p);
42     while(!Q.empty()){
43         p=Q.top();
44         Q.pop();
45         if(visited[p.e]) continue;
46         visited[p.e]=1;
47         for(i=0;i<ve[p.e].size();i++){
48             q=ve[p.e][i];
49             if(dis[q.y]>dis[p.e]+q.w){
50                 dis[q.y]=dis[p.e]+q.w;
51                 pp.e=q.y;pp.d=dis[q.y];
52                 Q.push(pp);
53             }
54         }
55     }
56 //    for(i=0;i<=n;i++) printf("%I64d ",dis[i]);
57 //    cout<<endl<<endl;
58 }
59
60 main()
61 {
62     int t, i, j, x, y, z;
63     cin>>t;
64     while(t--){
65         scanf("%lld %lld",&n,&m);
66         for(i=1;i<=n;i++) scanf("%d",&w[i]);
67         for(i=0;i<=n;i++) ve[i].clear();
68         mem p;
69         while(m--){
70             scanf("%d %d %d",&x,&y,&z);
71             p.y=y;p.w=z;
72             ve[x].push_back(p);
73             p.y=x;
74             ve[y].push_back(p);
75         }
76         dijkstra();
77
78         int f=1;
79         long long ans=0;
80         for(i=1;i<=n;i++){
81             ans+=dis[i]*w[i];
82             if(dis[i]==inf){
83                 f=0;break;
84             }
85         }
86         if(!f) printf("No Answer\n");
87         else printf("%lld\n",ans);
88     }
89 }
时间: 2024-10-26 16:18:06

POJ 3013 dijkstra+优先队列的相关文章

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA)

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n,树根为编号1,选择一些边,使得所有节点构成一棵树,选择边的代价是(子孙的点的重量)×(这条边的价值).求代价最小多少. 分析: 单看每个点被计算过的代价,很明显就是从根到节点的边的价值.所以这是个简单的单源最短路问题. 不过坑点还是很多的. 点的数量高达5w个,用矩阵存不行,只能用边存. 还有路径和结

POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n.树根为编号1,选择一些边.使得全部节点构成一棵树.选择边的代价是(子孙的点的重量)×(这条边的价值). 求代价最小多少. 分析: 单看每一个点被计算过的代价,非常明显就是从根到节点的边的价值.所以这是个简单的单源最短路问题. 只是坑点还是非常多的. 点的数量高达5w个,用矩阵存不行.仅仅能用边存. 还

poj 3013 Big Christmas Tree (dij+优先队列优化 求最短路)

模板 题意:给你一个图,1总是为根,每个边有单位价值,每个点有权重. 每条边的价值 = sum(后继节点权重)*边的单位价值. 求树的最小价值,即构成一棵树的n-1条边的最小价值. 算法: 1.因为每个边的价值都要乘以后来访问的节点的权重,而走到后来访问的点必经过这条边. 实际上总价值就是  到每个点的最短路径*这个点的权重. 2.但是这个题 数据量真的太大了,50000个点,50000条边. 写普通的dij算法tle. 必须加优先队列优化- - 据说spfa也能过,但是spfa算法不稳定- -

【poj 1724】 ROADS 最短路(dijkstra+优先队列)

ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12436 Accepted: 4591 Description N cities named with numbers 1 - N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that

POJ 2387-Til the Cows Come Home(最短路Dijkstra+优先队列)

Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30007   Accepted: 10092 Description Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the

地铁 Dijkstra(优先队列优化) 湖南省第五届省赛

传送门:地铁 思路:拆点,最短路:拆点比较复杂,所以对边进行最短路,spfa会tle,所以改用Dijkstra(优先队列优化) 模板 /************************************************************** Problem: User: youmi Language: C++ Result: Accepted Time: Memory: *****************************************************

poj 1511 Dijkstra的另一种用法---求其他点到源点的最短路

传送门:http://poj.org/problem?id=1511 题目其实到现在我都没读懂,到底是哪里看出来的,ans是源点到各个点最短路的和外加各个点到源点的最短路的和,不过重要的是学到dijkstra的另一种用法--求各个点到源点的距离,原理不难理解,就是把dijkstra求单源最短路径的过程逆过来: 1.取源点加入S集合,设其余点在T集合 2.找到达源点的最小边,将该边连的点加入S,更新T到S的各个点的最短路径,取最短的边,继续2的过程 而dijastra求单源最短路径的过程 1.取源

UVA 658 It&#39;s not a Bug, it&#39;s a Feature! (单源最短路,dijkstra+优先队列,变形,经典)

题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了:要打多久才能无bug?(同1补丁可重复打) 分析: n<=20,那么用位来表示bug的话有220=100万多一点.不用建图了,图实在太大了,用位图又不好玩.那么直接用隐式图搜索(在任意点,只要满足转移条件,任何状态都能转). 但是有没有可能每个状态都要搜1次啊?那可能是100万*100万啊,这样出题

poj 3159 dijkstra 最短路

Description During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher brought the kids of flymouse’s class a large bag of candies and had flymouse distribute them. All the kids loved candies very much and ofte