Gym - 100625D Destination Unknown 最短路

http://codeforces.com/gym/100625/attachments/download/3213/2013-benelux-algorithm-programming-contest-bapc-13-en.pdf

题意:给你一张无向图,t个可能的目的地,问在这t个点中哪些点的最短路中经过了g和h

思路:这是傻逼题,我直接dijstra用vector< set<int> > 保存路径, 最后再去判断下。。好像这并不是出题者想要的解法,不过时间还可以,300+ms

  1 #pragma comment(linker, "/STACK:1000000000")
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <fstream>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <deque>
  8 #include <vector>
  9 #include <queue>
 10 #include <string>
 11 #include <cstring>
 12 #include <map>
 13 #include <stack>
 14 #include <set>
 15 #define LL long long
 16 #define MAXN 100005
 17 #define INF 0x3f3f3f3f
 18 #define eps 1e-8
 19 using namespace std;
 20 struct Edge
 21 {
 22     int from, to, dist;
 23     Edge(int from, int to, int dist):from(from), to(to), dist(dist){};
 24 };
 25 struct HeapNode
 26 {
 27     int d, u;
 28     HeapNode(int d, int u):d(d), u(u){};
 29     bool operator <(const HeapNode& rhs) const{
 30         return d > rhs.d;
 31     }
 32 };
 33 vector< set<int> > road[MAXN];
 34 struct Dijstra
 35 {
 36     int n, m;
 37     vector<Edge> edges;
 38     vector<int> G[MAXN];
 39     bool done[MAXN];
 40     int d[MAXN];
 41     int p[MAXN];
 42 
 43     void init(int n){
 44         this->n = n;
 45         for(int i = 0; i <= n; i++){
 46             G[i].clear();
 47             road[i].clear();
 48         }
 49         edges.clear();
 50     }
 51 
 52     void AddEdge(int from, int to, int dist){
 53         edges.push_back(Edge(from, to, dist));
 54         m = edges.size();
 55         G[from].push_back(m - 1);
 56     }
 57 
 58     void dijstra(int s){
 59         priority_queue<HeapNode> Q;
 60         for(int i = 0; i <= n; i++){
 61             d[i] = INF;
 62         }
 63         d[s] = 0;
 64         memset(done, 0, sizeof(done));
 65         Q.push(HeapNode(0, s));
 66         while(!Q.empty()){
 67             HeapNode x = Q.top();
 68             Q.pop();
 69             int u = x.u;
 70             if(done[u]) continue;
 71             done[u]  = true;
 72             for(int i = 0; i < G[u].size(); i++){
 73                 Edge& e = edges[G[u][i]];
 74                 if(d[e.to] > d[u] + e.dist){
 75                     d[e.to] = d[u] + e.dist;
 76                     road[e.to].clear();
 77                     if(road[u].empty()){
 78                         set<int> tmp;
 79                         tmp.clear();
 80                         tmp.insert(u);
 81                         road[e.to].push_back(tmp);
 82                     }
 83                     else{
 84                         for(int j = 0; j < road[u].size(); j++){
 85                             road[e.to].push_back(road[u][j]);
 86                             road[e.to][j].insert(u);
 87                         }
 88                     }
 89                     p[e.to] = G[u][i];
 90                     Q.push(HeapNode(d[e.to], e.to));
 91                 }
 92                 else if(d[e.to] == d[u] + e.dist){
 93                     int w = road[e.to].size();
 94                     for(int j = 0; j < road[u].size(); j++){
 95                         road[e.to].push_back(road[u][j]);
 96                         road[e.to][w + j].insert(u);
 97                     }
 98                 }
 99             }
100         }
101     }
102 };
103 int n, m, t, g, h, s;
104 Dijstra p;
105 vector<int> res;
106 int main()
107 {
108 #ifndef ONLINE_JUDGE
109     freopen("in.txt", "r", stdin);
110     //freopen("out.txt", "w", stdout);
111 #endif // OPEN_FILE
112     int T;
113     scanf("%d", &T);
114     while(T--){
115         scanf("%d%d%d", &n, &m, &t);
116         scanf("%d%d%d", &s, &g, &h);
117         int x, y, z;
118         p.init(n);
119         for(int i = 1; i <= m; i++){
120             scanf("%d%d%d", &x, &y, &z);
121             p.AddEdge(x, y, z);
122             p.AddEdge(y, x, z);
123         }
124         p.dijstra(s);
125         res.clear();
126         for(int i = 1; i <= t; i++){
127             scanf("%d", &x);
128             for(int j = 0; j < road[x].size(); j++){
129                 road[x][j].insert(x);
130                 if(road[x][j].find(g) != road[x][j].end() && road[x][j].find(h) != road[x][j].end()){
131                     res.push_back(x);
132                     break;
133                 }
134             }
135         }
136         sort(res.begin(), res.end());
137         int w = res.size();
138         for(int i = 0; i < w; i++){
139             printf("%d ", res[i]);
140         }
141         printf("\n");
142     }
143 }

 

转载于:https://www.cnblogs.com/macinchang/p/4718171.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值