Codeforces Gym 100338C Important Roads 最短路+Tarjan找桥
原题链接:http://codeforces.com/gym/100338/attachments/download/2136/20062007-winter-petrozavodsk-camp-andrew-stankevich-contest-22-asc-22-en.pdf
题意
给你一个无向图,要从1走到n,问你哪些边去掉之后就没法走原本的最短路了。
题解
跑两发最短路,顺着跑一发,倒着跑一发,对于边(u,v),如果w(u,v)+d[u]+rd[v]或者w(u,v)+d[v]+rd[u]等于最短路,那么边(u,v)就是某条最短路上的边,将这些边标记好后,跑一发Tarjan找桥,这些桥就是答案。需要注意的是有重边。
代码
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<set>
#define INF 21234567890
#define MAX_N 20004
#define MAX_M 112345
using namespace std; typedef long long ll; struct node {
public:
int u;
ll c; node(int uu, ll cc) : u(uu), c(cc) { } node() { } bool operator<(const node &a)const {
return c > a.c;
}
}; struct edge {
public:
int to;
ll cost;
bool isShort;
int id;
edge(int t, ll c,int i) : to(t), cost(c), isShort(), id(i){ } edge() { }
};
priority_queue<node> que;
int n, m; struct fuck {
public:
int u, v, c, id; fuck(int uu, int vv, int cc, int i) : u(uu), v(vv), c(cc), id(i) { } fuck() { }
bool operator<(const fuck &a)const{
if(a.u==u){
if(a.v==v)return a.c<c;
else return a.v<v;
}
return a.u<u;
}
}; set<fuck> se; vector<edge> G[MAX_N]; void dijkstra(int s,ll d[]) {
while (que.size())que.pop();
fill(d, d + n + , INF);
que.push(node(s, ));
d[s] = ;
while (que.size()) {
node now = que.top();
que.pop();
int u = now.u;
ll c = now.c;
if (d[u] < c)continue;
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].to;
if (d[v] > d[u] + G[u][i].cost) {
d[v] = d[u] + G[u][i].cost;
que.push(node(v, d[v]));
}
}
}
} ll d[MAX_N],rd[MAX_N]; int father[MAX_N];
int dfn[MAX_N],low[MAX_N],ind=;
bool vis[MAX_N];
int sum=;
bool isBridge[MAX_M]; bool hasSame[MAX_M]; void Tarjan(int u,int p) {
father[u] = p;
dfn[u] = low[u] = ++ind;
vis[u] = ;
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].to;
if (v == p||(!G[u][i].isShort))continue;
if (!vis[v]) {
Tarjan(v,u);
low[u] = min(low[u], low[v]);
if (low[v] > dfn[u]) {
sum++;
isBridge[G[u][i].id] = ;
}
}
else
low[u] = min(dfn[v], low[u]);
}
} bool ans[MAX_M]; int main() {
freopen("important.in", "r", stdin);
freopen("important.out", "w", stdout);
scanf("%d%d", &n, &m);
for (int i = ; i < m; i++) {
int u, v;
int c;
scanf("%d%d%d", &u, &v, &c);
fuck f(u,v,c,i);
fuck f0(v,u,c,i);
auto it=se.find(f);
if(it!=se.end()){
hasSame[it->id]=;
continue;
}
it=se.find(f0);
if(it!=se.end()){
hasSame[it->id]=;
continue;
}
se.insert(f);
G[u].push_back(edge(v, c, i));
G[v].push_back(edge(u, c, i));
} dijkstra(, d);
dijkstra(n, rd);
ll sd = d[n];
for (int i = ; i <= n; i++)
for (int j = ; j < G[i].size(); j++) {
int u = i, v = G[i][j].to;
if (d[u] + rd[v] + G[i][j].cost == sd || d[v] + rd[u] + G[i][j].cost == sd)
G[i][j].isShort = ;
}
Tarjan(,);
int tot = ;
for (int i = ; i <= n; i++)
for (int j = ; j < G[i].size(); j++)
if (isBridge[G[i][j].id])
ans[G[i][j].id + ] = ;
for (int i = ; i <= m; i++)if ((!hasSame[i-])&&ans[i])tot++;
printf("%d\n", tot);
for (int i = ; i <= m; i++)
if (ans[i]&&(!hasSame[i-]))
printf("%d ", i);
printf("\n");
return ;
}
Codeforces Gym 100338C Important Roads 最短路+Tarjan找桥的更多相关文章
- Gym - 100338C  Important Roads  最短路+tarjan
		
题意:给你一幅图,问有多少条路径使得去掉该条路后最短路发生变化. 思路:先起始两点求两遍单源最短路,利用s[u] + t[v] + G[u][v] = dis 找出所有最短路径,构造新图.在新图中找到 ...
 - 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 ...
 - Tarjan找桥和割点与点连通分量与边连通分量【未成形】
		
之前只学了个强连通Tarjan算法,然后又摸了缩点操作: 然后今天在lightoj摸了一道模板题,是求所有桥的题: 然后发现,要把:割点,割点集合,双连通,最小割边集合(桥),点连通分量,边连通分量都 ...
 - Codeforces.567E.President and Roads(最短路 Dijkstra)
		
题目链接 \(Description\) 给定一张有向图,求哪些边一定在最短路上.对于不一定在最短路上的边,输出最少需要将其边权改变多少,才能使其一定在最短路上(边权必须为正,若仍不行输出NO). \ ...
 - Codeforces 160D Edges in MST tarjan找桥
		
Edges in MST 在用克鲁斯卡尔求MST的时候, 每个权值的边分为一类, 然后将每类的图建出来, 那些桥就是必须有的, 不是桥就不是必须有. #include<bits/stdc++.h ...
 - Codeforces GYM 100876 J - Buying roads 题解
		
Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...
 - Codeforces 806 D.Prishable Roads
		
Codeforces 806 D.Prishable Roads 题目大意:给出一张完全图,你需要选取其中的一些有向边,连成一个树形图,树形图中每个点的贡献是其到根节点路径上每一条边的边权最小值,现在 ...
 - ACdream 1415 Important Roads
		
Important Roads Special JudgeTime Limit: 20000/10000MS (Java/Others)Memory Limit: 128000/64000KB (Ja ...
 
随机推荐
- STM32F407VET6之IAR之ewarm7.80.4工程建立(基于官方固件库1.6版本)  的工程文件目录
			
最后整理结构如下所示,├─cmsis│ startup_stm32f401xx.s│ startup_stm32f40xx.s│ startup_stm32f40_41xxx.s│ startup_s ...
 - 设置ubuntu12.04的dasher-自动隐藏,左上角
			
点击右上角的齿轮,--> “system setting”--“Appearance” 在“Look”标签中: Theme:Ambiance Launch icon size :32 选择桌面背 ...
 - Hadoop4.2HDFS测试报告之六
			
测试结论 第一组数据作表格作图: 第二组数据作表格作图: 根据以上图分析得出以下结论: 1. 本地存储的读写速率基本保持23M左右,说明本地存储比较稳定. 2. HDFS存储两个数据节点的读写速率性能 ...
 - hdu3487Play with Chain
			
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
 - 【Linux】tcpdump命令详解
			
tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析. 它支持针对网络层.协议.主机.网络或端口的过滤,并提供and.or.not等逻辑语句帮你过滤到无用的信息. 实用命令实例 1.普通 ...
 - Codeforces Round #410 (Div. 2) A. Mike and palindrome
			
A. Mike and palindrome time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
 - java环境配置classpath和path变量的作用及设置方法
			
1.path:指定cmd中命令执行文件所在的路径.比如javac.java两个可执行文件在jdk的bin目录下,如果path值含有这个bin目录,在cmd下执行这两个命令的时候就会到path指定的目录 ...
 - [CQOI2010] 扑克牌 (二分答案,巧解)
			
Description 你有n种牌,第i种牌的数目为ci.另外有一种特殊的牌:joker,它的数目是m.你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1套 ...
 - mybatis读取oracle中blob
			
controller: byte[] blob = commonService.getPersonImage(bean.getIdCard()); String base64 = new String ...
 - eclipse  testng插件安装
			
1.安装Testng 在Eclipse中,点击Help→Install new software→点击Add,在location中输入http://beust.com/eclipse ,选择TestN ...