C - Important Roads
Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88926#problem/C

Description

The city where Georgie lives has n junctions some of which are connected by bidirectional roads. Every day Georgie drives from his home to work and back. But the roads in the city where Georgie lives are very bad, so they are very often closed for repair. Georgie noticed that when some roads are closed he still can get from home to work in the same time as if all roads were available. But there are such roads that if they are closed for repair the time Georgie needs to get from home to work increases, and sometimes Georgie even cannot get to work by a car any more. Georgie calls such roads important. Help Georgie to find all important roads in the city.

Input

The first line of the input file contains n and m — the number of junctions and roads in the city where Georgie lives, respectively (2 ≤ n ≤ 20 000, 1 ≤ m ≤ 100 000). Georgie lives at the junction 1 and works at the junction n. The following m lines contain information about roads. Each road is specified by the junctions it connects and the time Georgie needs to drive along it. The time to drive along the road is positive and doesn’t exceed 100 000. There can be several roads between a pair of junctions, but no road connects a junction to itself. It is guaranteed that if all roads are available, Georgie can get from home to work.

Output

Output l — the number of important roads — at the first line of the output file. The second line must contain l numbers, the numbers of important roads. Roads are numbered from 1 to m as they are given in the input file.

Sample Input

6 7
1 2 1
2 3 1
2 5 3
1 3 2
3 5 1
2 4 1
5 6 2

Sample Output

2
5 7

HINT

题意

给你一个无向图,问你里面有多少个important道路

重要的道路就是指这条路去掉之后,整个图的最短路长度会发生变化

题解

跑tarjan之后,如果这个边是桥的话,就输出就好了

和codeforces #314的E题几乎一模一样

代码:

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = ;
#define INF (1LL<<61)
typedef long long ll; struct Dijkstra {
struct node {
ll d;
int u;
bool operator < (const node& b) const {
return d > b.d;
}
node() {}
node(ll _d, int _u): d(_d), u(_u) {}
}; struct Edge {
int from, to, id;
ll dist;
Edge() {}
Edge(int u, int v, ll w) : from(u), to(v), dist(w){}
};
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn];
ll 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, ll dist) {
edges.push_back(Edge(from, to, dist));
m = edges.size();
G[from].push_back(m-);
} void dijkstra(int s) {
priority_queue<node> Q;
for (int i = ; i <= n; i++) d[i] = INF;
d[s] = ;
memset(done, , sizeof(done));
Q.push(node(, s));
while (!Q.empty()) {
node 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(node(d[e.to], e.to));
}
}
}
}
} S, T; int dfn[maxn]; // 时间戳
int dfs_clock; // dfs时间变量
int low[maxn]; // u及u的后代在DFS树上能够到达的最早的祖先 struct Edge {
int u, v, w, id;
Edge(int a=, int b=, int w=, int c=) : u(a), v(b), w(w), id(c) {}
} e[*maxn]; vector<Edge> G[maxn];
bool isbridge[*maxn]; int dfs(int u, int la) {
int lowu = dfn[u] = ++dfs_clock; // dfs_clock在调用dfs前要初始化为0
int child = ; // 子节点个数
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].v;
if (!dfn[v]) { // 未访问过,树边
int lowv = dfs(v, G[u][i].id);
lowu = min(lowu, lowv);
if (lowv > dfn[u]) { // 判断桥
isbridge[G[u][i].id] = ;
}
}
else if (dfn[v] < dfn[u] && G[u][i].id != la) { // 反向边
lowu = min(lowu, dfn[v]);
}
}
low[u] = lowu;
return lowu;
} int ison[*maxn];
int can[*maxn];
vector<int> ans;
int main() {
freopen("important.in","r",stdin);
freopen("important.out","w",stdout);
int n, m, s, t;
scanf("%d%d", &n, &m);
s = ,t = n;
S.init(n+);
T.init(n+);
int u, v, w;
for (int i = ; i <= m; i++){
scanf("%d%d%d", &u, &v, &w);
e[i*-] = Edge(u, v, w, i*-);
S.addEdge(u, v, w);
T.addEdge(v, u, w);
e[i*] = Edge(v,u,w,i*);
S.addEdge(v,u,w);
T.addEdge(u,v,w);
}
m*=;
S.dijkstra(s);
T.dijkstra(t);
ll ddd = S.d[t];
ll delta;
for (int i = ; i <= m; i++) {
u = e[i].u;
v = e[i].v;
w = e[i].w;
if (S.d[u] + w == S.d[v] && T.d[v] + w == T.d[u]) {
G[u].push_back(Edge(u, v, w, i));
G[v].push_back(Edge(v, u, w, i));
ison[i] = ;
}
}
dfs(s, -); for (int i = ; i <= m; i++) {
if (isbridge[i]) {
ans.push_back((i+)/);
}
} sort(ans.begin(),ans.end());
ans.erase(unique(ans.begin(),ans.end()),ans.end()); printf("%d\n",ans.size());
for(int i=;i<ans.size();i++)
printf("%d ",ans[i]);
printf("\n"); return ;
}

Codeforces Gym 100338C C - Important Roads tarjan的更多相关文章

  1. Codeforces GYM 100876 J - Buying roads 题解

    Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...

  2. Codeforces Gym 100338C Important Roads 最短路+Tarjan找桥

    原题链接:http://codeforces.com/gym/100338/attachments/download/2136/20062007-winter-petrozavodsk-camp-an ...

  3. codeforces Gym 100338C Important Roads (重建最短路图)

    正反两次最短路用于判断边是不是最短路上的边,把最短路径上的边取出来建图.然后求割边.注意重边,和卡spfa. 正权,好好的dijkstra不用,用什么spfa? #include<bits/st ...

  4. codeforces GYM 100114 J. Computer Network tarjan 树的直径 缩点

    J. Computer Network Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Des ...

  5. ACdream 1415 Important Roads

    Important Roads Special JudgeTime Limit: 20000/10000MS (Java/Others)Memory Limit: 128000/64000KB (Ja ...

  6. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

  7. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  8. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  9. 【Codeforces Gym 100725K】Key Insertion

    Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...

随机推荐

  1. 【转】iOS UITableView的方法解析

    原文网址:http://www.cnblogs.com/wfwenchao/articles/3718742.html - (void)viewDidLoad { [super viewDidLoad ...

  2. Android-setDefaultKeyMode方法

    在Activity中的onCreate()方法中使用setDefaultKeyMode()可以做到在当前activity中打开拨号器.执行快捷键.启动本地搜索.启动全局搜索: setDefaultKe ...

  3. cgroup的测试数据

    [root@xxxx /cgroup/memory/rule3021]#cat memory.limit_in_bytes503316480   480M [root@xxxx /cgroup/mem ...

  4. fastdb中的位图应用

    位图内存管理: 每块内存用一个二进制位表示它的使用状态,如果该块内存被占用,则把对应位图中的对应位置1,如果空闲则置0,原理十分简单.计算机里面处理的位数最少的变量是字节(byte),所以也就是8位做 ...

  5. 将webkit内核封装为duilib的浏览器控件

    转载请说明出处,谢谢~~ 原本的duilib是自带浏览器控件的,但是使用了IE内核,我在做仿酷狗音乐播放器时,在右侧乐库要用到浏览器控件,而我使用自带的IE控件却发现了不少缺点,这也是duilib一直 ...

  6. bzoj 1798 [Ahoi2009]Seq 维护序列seq(线段树+传标)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1798 [题意] 给定一个序列,要求提供区间乘/加,以及区间求和的操作 [思路] 线段树 ...

  7. sgu 194 Reactor Cooling(有容量上下界的无源无汇可行流)

    [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20757 [题意] 求有容量上下界的无源无汇可行流. [思路] ...

  8. bzoj 2595 [Wc2008]游览计划(斯坦纳树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...

  9. HDU 1536 sg-NIM博弈类

    题意:每次可以选择n种操作,玩m次,问谁必胜.c堆,每堆数量告诉. 题意:sg—NIM系列博弈模板题 把每堆看成一个点,求该点的sg值,异或每堆sg值. 将多维转化成一维,性质与原始NIM博弈一样. ...

  10. Struts2类型转换器

    概述 A .从一个HTML 表单到一个 Action 对象,类型转换是从字符串到非字符串.    –HTTP没有"类型" 的概念.每一项表单输入只可能是一个字符串或一个字符串数组. ...