Gym - 100338C Important Roads 最短路+tarjan
题意:给你一幅图,问有多少条路径使得去掉该条路后最短路发生变化。
思路:先起始两点求两遍单源最短路,利用s[u] + t[v] + G[u][v] = dis 找出所有最短路径,构造新图。在新图中找到所有的桥输出就可以了。
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define LL long long
#define eps 1e-8
#define INF 0x3f3f3f3f
#define MAXN 20005
#define MAXM 100005
using namespace std; struct Edge
{
int from, to, dist, pos;
Edge(int from, int to, int dist, int pos) :from(from), to(to), dist(dist), pos(pos){};
};
struct HeapNode
{
int d, u;
HeapNode(int d, int u) :d(d), u(u){};
bool operator <(const HeapNode& rhs) const{
return d > rhs.d;
}
};
struct Dijstra
{
int n, m;
vector<Edge> edges;
vector<int> G[MAXN];
bool done[MAXN];
int d[MAXN];
int p[MAXN]; void init(int n){
this->n = n;
for (int i = ; i <= n; i++){
G[i].clear();
}
edges.clear();
} void AddEdge(int from, int to, int dist, int pos = ){
edges.push_back(Edge(from, to, dist, pos));
m = edges.size();
G[from].push_back(m - );
} void dijstra(int s){
priority_queue<HeapNode> Q;
for (int i = ; i <= n; i++){
d[i] = INF;
}
d[s] = ;
memset(done, , sizeof(done));
Q.push(HeapNode(, s));
while (!Q.empty()){
HeapNode x = Q.top();
Q.pop();
int u = x.u;
if (done[u]) continue;
done[u] = true;
for (int i = ; i < G[u].size(); i++){
Edge& e = edges[G[u][i]];
if (d[e.to] > d[u] + e.dist){
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push(HeapNode(d[e.to], e.to));
}
else if (d[e.to] == d[u] + e.dist){ }
}
}
}
};
int pre[MAXN], isbridge[MAXM], low[MAXN];
vector<Edge> G[MAXN];
int dfs_clock;
int dfs(int u, int father){
int lowu = pre[u] = ++dfs_clock;
//int child = 0;
for (int i = ; i < G[u].size(); i++){
int v = G[u][i].to;
if (!pre[v]){
//child++;
int lowv = dfs(v, G[u][i].pos);
lowu = min(lowu, lowv);
if (lowv > pre[u]){
isbridge[G[u][i].pos] = true;
}
}
else if (pre[v] < pre[u] && G[u][i].pos != father){
lowu = min(lowu, pre[v]);
}
}
low[u] = lowu;
return lowu;
}
Dijstra s, t;
vector<Edge> edges; int res[MAXM];
int main()
{
#ifdef ONLINE_JUDGE
freopen("important.in", "r", stdin);
freopen("important.out", "w", stdout);
#endif // OPEN_FILE
int n, m;
while (~scanf("%d%d", &n, &m)){
s.init(n);
t.init(n);
edges.clear();
int x, y, z;
for (int i = ; i <= m; i++){
scanf("%d%d%d", &x, &y, &z);
edges.push_back(Edge(x, y, z, i));
edges.push_back(Edge(y, x, z, i));
s.AddEdge(x, y, z);
s.AddEdge(y, x, z);
t.AddEdge(x, y, z);
t.AddEdge(y, x, z);
}
s.dijstra();
t.dijstra(n);
LL dis = s.d[n];
//把所有最短路径找出来,在里面找出所有的桥就是答案
for (int i = ; i < edges.size(); i++){
Edge e = edges[i];
if (s.d[e.from] + e.dist + t.d[e.to] == dis){
G[e.from].push_back(Edge(e.from, e.to, e.dist, e.pos));
G[e.to].push_back(Edge(e.to, e.from, e.dist, e.pos)); }
}
dfs_clock = ;
memset(isbridge, , sizeof(isbridge));
memset(pre, , sizeof(pre));
dfs(, -);
int ans = ;
for (int i = ; i <= m; i++){
if (isbridge[i]){
ans++;
res[ans] = i;
}
}
printf("%d\n", ans);
for (int i = ; i <= ans; i++){
printf("%d ", res[i]);
}
printf("\n");
}
}
Gym - 100338C Important Roads 最短路+tarjan的更多相关文章
- Codeforces Gym 100338C Important Roads 最短路+Tarjan找桥
原题链接:http://codeforces.com/gym/100338/attachments/download/2136/20062007-winter-petrozavodsk-camp-an ...
- codeforces Gym 100338C Important Roads (重建最短路图)
正反两次最短路用于判断边是不是最短路上的边,把最短路径上的边取出来建图.然后求割边.注意重边,和卡spfa. 正权,好好的dijkstra不用,用什么spfa? #include<bits/st ...
- Codeforces Gym 100338C C - Important Roads tarjan
C - Important RoadsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contes ...
- ACdream 1415 Important Roads
Important Roads Special JudgeTime Limit: 20000/10000MS (Java/Others)Memory Limit: 128000/64000KB (Ja ...
- CF Destroying Roads (最短路)
Destroying Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路
题目链接: 题目 D. Destroying Roads time limit per test 2 seconds memory limit per test 256 megabytes input ...
- Codeforces Round #Pi (Div. 2) E. President and Roads 最短路+桥
题目链接: http://codeforces.com/contest/567/problem/E 题意: 给你一个带重边的图,求三类边: 在最短路构成的DAG图中,哪些边是必须经过的: 其他的(包括 ...
- cf567E. President and Roads(最短路计数)
题意 题目链接 给出一张有向图,以及起点终点,判断每条边的状态: 是否一定在最短路上,是的话输出'YES' 如果不在最短路上,最少减去多少权值会使其在最短路上,如果减去后的权值\(< 1\),输 ...
- 【poj 1724】 ROADS 最短路(dijkstra+优先队列)
ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12436 Accepted: 4591 Description N ...
随机推荐
- layui框架下的摸索与学习
一.table表格内的查询 1.单个条件查询: 主要代码: <%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/1/14 ...
- URAL 2027 2028 两个有趣的题
这两个题,讲的是有一种奇怪的语言,代码是一种二维的矩阵. 前一个题,是根据所给的要求,写一个简单的解释器. 后一个题,是用那种语言写一个简单的小程序. 挺有意思的,所以在这里纪念一下.顺便那个语言的原 ...
- C++根据扩展名获取文件图标、类型
简述 在Windows系统中,根据扩展名来区分文件类型,比如:.txt(文本文件)..exe(可执行程序).*.zip(压缩文件),下面,我们来根据扩展名来获取对应的文件图标.类型. 简述 源码 源码 ...
- C++友元(Friend)简介
相对Java而言,友元是C++中特有的一种元素,再加上<C++ Primer>也并没有太具体的样例,所以刚接触这个概念的时候懵了非常久,即是自己总结一下,也希望能帮到大家,以下来讲讲友元的 ...
- 51nod-1131: 覆盖数字的数量
[传送门:51nod-1131] 简要题意: 给出A,B,表示有一个区间为A到B 给出X,Y,表示有一个区间为X到Y 求出X到Y中能够被A到B中的数(可重复)相加得到的不同的数的个数 题解: 乱搞题, ...
- es6 --- class 类的继承使用
传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...
- 线程1—Thread
随便选择两个城市作为预选旅游目标.实现两个独立的线程分别显示10次城市名,每次显示后休眠一段随机时间(1000ms以内),哪个先显示完毕,就决定去哪个城市.分别用Runnable接口和Thread类实 ...
- Java 类和对象7
创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它. public class sanjiaoxing { private double a; private double b; pri ...
- SharePoint 学习快速导航
根据我的学习过程,会不断的增加一些学习的快速链接 . 入门篇 SharePoint入门链接,针对刚刚开始了解SharePoint 的朋友,我也是处在入门的状态,随后会慢慢的累积增加 安装 | 部署 | ...
- 如何在一个 U 盘上安装多个 Linux 发行版
作者: Ambarish Kumar 译者: LCTT geekpi 本教程介绍如何在一个 U 盘上安装多个 Linux 发行版.这样,你可以在单个 U 盘上享受多个现场版live Linux 发行版 ...