您的位置:首页 > 其它

Gym - 100338C Important Roads 最短路+tarjan

2016-01-06 15:39 197 查看
题意:给你一幅图,问有多少条路径使得去掉该条路后最短路发生变化。
思路:先起始两点求两遍单源最短路,利用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
;
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 }


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: