https://vjudge.net/problem/Aizu-2249
感觉这题和2017女生赛的Deleting Edge思路很像,都是先找最短路,然后替换边的。
但是这题用最朴素的dijkstra的话memory limit exceed了,看了下超了约7倍无望。。。
不得已这时候不得不学dijkstra的堆优化了。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<stack> 8 #define lson l, m, rt<<1 9 #define rson m+1, r, rt<<1|1 10 #define INF 0x3f3f3f3f 11 typedef unsigned long long ll; 12 using namespace std; 13 int n, m, a, b, d, c; 14 int dist[1010], t[1010][10010], p[1010][1010]; 15 int vis[1010]; 16 void dijkstra() 17 { 18 memset(vis, 0, sizeof(vis)); 19 for(int i = 1; i <= n; i++){ 20 dist[i] = INF; 21 } 22 dist[1] = 0; 23 for(int i = 1; i <= n; i++){ 24 int mini = INF, k = -1; 25 for(int j = 1; j <= n; j++){ 26 if(!vis[j]&&mini > dist[j]){ 27 mini = dist[j]; 28 k = j; 29 } 30 } 31 vis[k] = 1; 32 for(int j = 1; j <= n; j++){ 33 if(!vis[j]&&dist[j] > dist[k]+t[k][j]){ 34 dist[j] = dist[k]+t[k][j]; 35 } 36 } 37 } 38 } 39 int main() 40 { 41 while(cin >> n >> m){ 42 if(!n&&!m) break; 43 for(int i = 1; i <= n; i++){ 44 for(int j = 1; j <= n; j++){ 45 if(i == j) t[i][j] = 0, p[i][j] = 0; 46 else t[i][j] = INF; p[i][j] = INF; 47 } 48 } 49 for(int i = 0; i < m; i++){ 50 cin >> a >> b >> d >> c; 51 t[a][b] = d; t[b][a] = d; 52 p[a][b] = c; p[b][a] = c; 53 } 54 dijkstra(); 55 int sum=0; 56 for(int i = 2; i <= n; i++){//这里记得要从2开始,从一开始下面无法更新mini,而且反正i=1的时候mini也是0,就直接跳过了 57 int mini = INF; 58 for(int j = 1; j <= n; j++){ 59 if((dist[i] == dist[j]+t[j][i])&&mini>p[j][i]){ 60 mini = p[j][i]; 61 } 62 } 63 sum += mini; 64 } 65 cout << sum << endl; 66 } 67 return 0; 68 }
优先队列、vector容器、pair优化
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<stack> 8 #define lson l, m, rt<<1 9 #define rson m+1, r, rt<<1|1 10 #define INF 0x3f3f3f3f 11 typedef unsigned long long ll; 12 using namespace std; 13 int n, m, a, b, d, c; 14 int dist[10010]; 15 struct edge{ 16 int to, d, cost; 17 //edge(int a, int b, int c):to(a),d(b),cost(c){ } 18 }; 19 typedef pair<int, int> P; 20 vector<edge> G[10010]; 21 void dijkstra() 22 { 23 priority_queue<P, vector<P>, greater<P> > q; 24 for(int i = 1; i <= n; i++) dist[i] = INF; 25 dist[1] = 0; 26 q.push(P(0, 1)); 27 while(!q.empty()){ 28 P p = q.top(); q.pop(); 29 int v = p.second; 30 if(dist[v] < p.first) continue; 31 for(int i = 0; i < G[v].size(); i++){ 32 edge e = G[v][i]; 33 if(dist[e.to] > dist[v]+e.d){ 34 dist[e.to] = dist[v]+e.d; 35 q.push(P(dist[e.to], e.to)); 36 } 37 } 38 } 39 } 40 int main() 41 { 42 while(cin >> n >> m){ 43 if(!n&&!m) break; 44 for(int i = 0; i <= n; i++){ 45 G[i].clear(); 46 } 47 for(int i = 0; i < m; i++){ 48 cin >> a >> b >> d >> c; 49 G[a].push_back(edge{b, d, c}); 50 G[b].push_back(edge{a, d, c}); 51 } 52 dijkstra(); 53 /*for(int i = 1; i <= n; i++){ 54 cout << dist[i] << " "; 55 }*/ 56 int sum = 0; 57 for(int i = 2; i <= n; i++){ 58 int mini = INF; 59 for(int j = 0; j < G[i].size(); j++){ 60 edge e = G[i][j]; 61 if(dist[e.to]+e.d == dist[i]){//这里注意,一开始e.d错放到等式右边了 62 mini = min(mini, e.cost); 63 } 64 } 65 sum += mini; 66 } 67 cout << sum << endl; 68 } 69 return 0; 70 }