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 ...
随机推荐
- Python中的端口协议之基于UDP协议的通信传输
UDP协议: 1.python中基于udp协议的客户端与服务端通信简单过程实现 2.udp协议的一些特点(与tcp协议的比较) 3.利用socketserver模块实现udp传输协议的并 ...
- matplotlib学习记录 六
# 绘制多数据条形图 # 假设你知道了列表a中电影分别在2017-09-14(b_14),2017-09-15(b_15), # 2017-09-16(b_16)三天的票房,为了展示列表中电影本身的票 ...
- HDU - 5884 Sort (二分答案+贪心)
有n个数字,你需要把这n个数字合成一个数字,每次只能把k个数字合并成一个,花费为这k个数字的和. 给一个最大花费,问不超过这个最大花费的情况下,k的最小值. Sample Input 1 5 25 1 ...
- Linux学习-Linux的账号与群组
使用者识别码: UID 与 GID Linux 主机并不会直接认识 你的"帐号名称"的,他仅认识 ID 啊 (ID 就是一组号码啦). 由于计算机仅认识 0 与 1,所 以主机对于 ...
- selenium2等待元素加载
1.硬性等待 Thread.sleep(8000); 所谓的硬性等待就是,执行完相应操作就等待我设置的8s.无论网速快与慢,网速快的话,也许5s就打开网页了,可是程序必须接着等待剩下的3秒. 网速慢的 ...
- 基于JQuery的WEB套打设计器jatoolsPrinter1.0
开发web套打应用时,如快递单打印,一般要经过以下步骤:1. 扫描快递单据,保存成一个图片文件2. 将底图作成<img>3. 在<img>上放置打印项,试着打印到打印机,观察有 ...
- dubbo基础文档
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用架构 当网站流量很小时,只需一个应用, ...
- [Cake] 2. dotnet 全局工具 cake
在上篇博客[Cake] 1. CI中的Cake中介绍了如何在CI中利用Cake来保持与CI/CD环境的解耦. 1. 简化cake的安装 当时dotnet 2.1还未正式发布,dotnet 还没有工具的 ...
- Django创建
Pycharm里面Django模块安装及项目创建和启动: Pycharm里面Django模块安装(也可以指定安装源): 创建Django项目: 注意切换到合适的目录进行安装 diango-admin ...
- TOJ 4493 Remove Digits 贪心
4493: Remove Digits Description Given an N-digit number, you should remove K digits and make the new ...