Gym - 100338C Important Roads 最短路+tarjan

题意:给你一幅图,问有多少条路径使得去掉该条路后最短路发生变化。

思路:先起始两点求两遍单源最短路,利用s[u] + t[v] + G[u][v] = dis 找出所有最短路径,构造新图。在新图中找到所有的桥输出就可以了。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <fstream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <deque>
  7 #include <vector>
  8 #include <queue>
  9 #include <string>
 10 #include <cstring>
 11 #include <map>
 12 #include <stack>
 13 #include <set>
 14 #define LL long long
 15 #define eps 1e-8
 16 #define INF 0x3f3f3f3f
 17 #define MAXN 20005
 18 #define MAXM 100005
 19 using namespace std;
 20 
 21 struct Edge
 22 {
 23     int from, to, dist, pos;
 24     Edge(int from, int to, int dist, int pos) :from(from), to(to), dist(dist), pos(pos){};
 25 };
 26 struct HeapNode
 27 {
 28     int d, u;
 29     HeapNode(int d, int u) :d(d), u(u){};
 30     bool operator <(const HeapNode& rhs) const{
 31         return d > rhs.d;
 32     }
 33 };
 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         }
 48         edges.clear();
 49     }
 50 
 51     void AddEdge(int from, int to, int dist, int pos = 0){
 52         edges.push_back(Edge(from, to, dist, pos));
 53         m = edges.size();
 54         G[from].push_back(m - 1);
 55     }
 56 
 57     void dijstra(int s){
 58         priority_queue<HeapNode> Q;
 59         for (int i = 0; i <= n; i++){
 60             d[i] = INF;
 61         }
 62         d[s] = 0;
 63         memset(done, 0, sizeof(done));
 64         Q.push(HeapNode(0, s));
 65         while (!Q.empty()){
 66             HeapNode x = Q.top();
 67             Q.pop();
 68             int u = x.u;
 69             if (done[u]) continue;
 70             done[u] = true;
 71             for (int i = 0; i < G[u].size(); i++){
 72                 Edge& e = edges[G[u][i]];
 73                 if (d[e.to] > d[u] + e.dist){
 74                     d[e.to] = d[u] + e.dist;
 75                     p[e.to] = G[u][i];
 76                     Q.push(HeapNode(d[e.to], e.to));
 77                 }
 78                 else if (d[e.to] == d[u] + e.dist){
 79 
 80                 }
 81             }
 82         }
 83     }
 84 };
 85 int pre[MAXN], isbridge[MAXM], low[MAXN];
 86 vector<Edge> G[MAXN];
 87 int dfs_clock;
 88 int dfs(int u, int father){
 89     int lowu = pre[u] = ++dfs_clock;
 90     //int child = 0;
 91     for (int i = 0; i < G[u].size(); i++){
 92         int v = G[u][i].to;
 93         if (!pre[v]){
 94             //child++;
 95             int lowv = dfs(v, G[u][i].pos);
 96             lowu = min(lowu, lowv);
 97             if (lowv > pre[u]){
 98                 isbridge[G[u][i].pos] = true;
 99             }
100         }
101         else if (pre[v] < pre[u] && G[u][i].pos != father){
102             lowu = min(lowu, pre[v]);
103         }
104     }
105     low[u] = lowu;
106     return lowu;
107 }
108 Dijstra s, t;
109 vector<Edge> edges;
110 
111 int res[MAXM];
112 int main()
113 {
114 #ifdef ONLINE_JUDGE
115     freopen("important.in", "r", stdin);
116     freopen("important.out", "w", stdout);
117 #endif // OPEN_FILE
118     int n, m;
119     while (~scanf("%d%d", &n, &m)){
120         s.init(n);
121         t.init(n);
122         edges.clear();
123         int x, y, z;
124         for (int i = 1; i <= m; i++){
125             scanf("%d%d%d", &x, &y, &z);
126             edges.push_back(Edge(x, y, z, i));
127             edges.push_back(Edge(y, x, z, i));
128             s.AddEdge(x, y, z);
129             s.AddEdge(y, x, z);
130             t.AddEdge(x, y, z);
131             t.AddEdge(y, x, z);
132         }
133         s.dijstra(1);
134         t.dijstra(n);
135         LL dis = s.d[n];
136         //把所有最短路径找出来,在里面找出所有的桥就是答案
137         for (int i = 0; i < edges.size(); i++){
138             Edge e = edges[i];
139             if (s.d[e.from] + e.dist + t.d[e.to] == dis){
140                 G[e.from].push_back(Edge(e.from, e.to, e.dist, e.pos));
141                 G[e.to].push_back(Edge(e.to, e.from, e.dist, e.pos));
142 
143             }
144         }
145         dfs_clock = 0;
146         memset(isbridge, 0, sizeof(isbridge));
147         memset(pre, 0, sizeof(pre));
148         dfs(1, -1);
149         int ans = 0;
150         for (int i = 1; i <= m; i++){
151             if (isbridge[i]){
152                 ans++;
153                 res[ans] = i;
154             }
155         }
156         printf("%d\n", ans);
157         for (int i = 1; i <= ans; i++){
158             printf("%d ", res[i]);
159         }
160         printf("\n");
161     }
162 }

 

posted on 2015-09-12 01:27  张济  阅读(195)  评论(0编辑  收藏  举报

导航