Gym - 100338C Important Roads 最短路+tarjan

来源:互联网 发布:大智慧编程函数大全 编辑:程序博客网 时间:2024/06/11 22:50
题意:给你一幅图,问有多少条路径使得去掉该条路后最短路发生变化。

思路:先起始两点求两遍单源最短路,利用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_JUDGE115     freopen("important.in", "r", stdin);116     freopen("important.out", "w", stdout);117 #endif // OPEN_FILE118     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 }

 

0 0
原创粉丝点击