题意:给定一个无向图,要求构造一棵以1为根的树T,使得花费和最小。
边权(花费):S(边的price*S(边子孙节点的weight)),可以转化为S(第个点的weight*S(该点到源点每条边上的price))
即所求为:ans = Sdist[i] * weight[i]。因weight[i]是确定的,故原题转化为求最短路问题。
因题目数目较大,故用Dijkstra+heap优化。
1
#include<iostream>
2
#include<queue>
3
#include<limits>
4
#include<vector>
5
6
using namespace std;
7
8
typedef unsigned long long u64_T;
9
10
const int maxN = 50001;
11
const int maxM = 100010;
12
const u64_T INF = numeric_limits<u64_T>::max();
13
14
//边结构
15
struct Edge
16

{
17
int e;
18
u64_T p;
19
Edge *next;
20
};
21
22
//节点结构
23
struct Node
24

{
25
int v;
26
u64_T len;
27
28
bool operator < (const Node &node) const
29
{
30
return len < node.len;
31
}
32
};
33
34
Edge *G[maxN];
35
u64_T weight[maxN];
36
37
int mSet;
38
39
//输入时,加边
40
void addEdge(int u, int v, u64_T w)
41

{
42
Edge *ptr = new Edge;
43
ptr->e = v;
44
ptr->p = w;
45
ptr->next = G[u];
46
G[u] = ptr;
47
}
48
49
//Dijkstra算法求最短路
50
u64_T Dijkstra(int n,int s)
51

{
52
priority_queue<Node> q;
53
u64_T dist[maxN];
54
Node cur,nex;
55
56
for(int i = 1;i <= n;i++)
57
{
58
dist[i] = INF;
59
}
60
dist[s] = 0;
61
cur.v = s;
62
cur.len = 0;
63
q.push(cur);
64
65
while(!q.empty())
66
{
67
cur = q.top();
68
q.pop();
69
70
if( cur.len == dist[cur.v] )
71
{
72
for(Edge* ptr = G[cur.v]; ptr != NULL; ptr = ptr->next)
73
{
74
u64_T newDist = dist[cur.v] + ptr->p;
75
if( newDist < dist[ptr->e] )
76
{
77
dist[ptr->e] = newDist;
78
nex.v = ptr->e;
79
nex.len = newDist;
80
q.push(nex);
81
}
82
}
83
}
84
}
85
for(int i = 1;i <= n; i++)
86
{
87
if(dist[i] == INF)
88
{
89
return INF;
90
}
91
}
92
93
u64_T ans = 0;
94
for(int i = 1;i <= n; i++)
95
{
96
ans += dist[i] * weight[i];
97
}
98
return ans;
99
}
100
101
int main()
102

{
103
int T;
104
int v,e;
105
int a,b;
106
u64_T c;
107
108
int i;
109
110
scanf("%d",&T);
111
while(T--)
112
{
113
scanf("%d%d",&v,&e);
114
115
mSet = 0;
116
117
for(i=1;i<=v;i++)
118
{
119
scanf("%I64u",&weight[i]);
120
G[i] = NULL;
121
}
122
for(i=0;i<e;i++)
123
{
124
scanf("%d%d%I64u",&a,&b,&c);
125
addEdge(a,b,c);
126
addEdge(b,a,c);
127
}
128
129
u64_T ans = Dijkstra(v,1);
130
131
if(ans == INF)
132
{
133
printf("No Answer\n");
134
}
135
else
136
{
137
printf("%I64u\n",ans);
138
}
139
}
140
return 0;
141
}
142