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 }
时间: 2024-10-08 10:03:51

Gym - 100338C Important Roads 最短路+tarjan的相关文章

codeforces Gym 100338C Important Roads

正反两次最短路用于判断边是不是最短路上的边,把最短路径上的边取出来.然后求割边. #include<bits/stdc++.h> using namespace std; typedef long long ll; #define fi first #define se second #define bug(x) cout<<#x<<'='<<x<<endl; #define FOR(i,s,e) for(int i = s; i < e;

ACdream 1415 Important Roads

Important Roads Special JudgeTime Limit: 20000/10000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) Problem Description The city where Georgie lives has n junctions some of which are connected by bidirectional roads.      Every day Georgie

CodeForces 567E President and Roads(最短路 + tarjan)

CodeForces 567E President and Roads Description Berland has n cities, the capital is located in city s, and the historic home town of the President is in city t (s?≠?t). The cities are connected by one-way roads, the travel time for each of the road

Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)

题目地址:codeforces #pi (DIV2) E 题目很水..就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no. 但是!!!居然卡spfa!!那是不是说cf以后就不能用可以卡的算法了..完全可以出组数据来卡这些算法...比如spfa,isap... 于是为了这题,又看了一遍迪杰斯特拉算法.. 代码如下: #include <cstd

【poj 1724】 ROADS 最短路(dijkstra+优先队列)

ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12436 Accepted: 4591 Description N cities named with numbers 1 - N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that

LightOJ1002---Country Roads (最短路变形)

I am going to my home. There are many cities and many bi-directional roads between them. The cities are numbered from 0 to n-1 and each road has a cost. There are m roads. You are given the number of my city t where I belong. Now from each city you h

Codeforces 543B Destroying Roads(最短路)

题意: 给定一个n个点(n<=3000)所有边长为1的图,求最多可以删掉多少条边后,图满足s1到t1的距离小于l1,s2到t2的距离小于l2. Solution: 首先可以分两种情况讨论: 1:假设最后留下的边是互不相交的两条路径.此时的答案是n-s1到t1的最短路径-s2到t2的最短路径. 2:假设最后留下的边有重合的一段,此时只要枚举重合的这一段的起点和终点,就可以判断.注意此时要考虑这两条路径经过枚举的两点的顺序. 限制的条件比较多,可以用来剪枝的条件也很多. 由于所有边的长度为1,用DF

POJ 1724 ROADS 最短路

题目大意:有两个权值的最短路问题,要求满足费用不超过一定限度的情况下的最短路. 思路:正常的SPFA加一个小判断,就是当费用高于预期费用的时候不入队,顺便加一个pq吧. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100005 #define INF 0x3f3f3f

Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路 删边

题目:有n个城镇,m条边权为1的双向边让你破坏最多的道路,使得从s1到t1,从s2到t2的距离分别不超过d1和d2. #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #in