炸铁路
题目描述
A 国派出将军 uim,对 B 国进行战略性措施,以解救涂炭的生灵。
B 国有 n n n 个城市,这些城市以铁路相连。任意两个城市都可以通过铁路直接或者间接到达。
uim 发现有些铁路被毁坏之后,某两个城市无法互相通过铁路到达。这样的铁路就被称为 key road。
uim 为了尽快使该国的物流系统瘫痪,希望炸毁铁路,以达到存在某两个城市无法互相通过铁路到达的效果。
然而,只有一发炮弹(A 国国会不给钱了)。所以,他能轰炸哪一条铁路呢?
输入格式
第一行 n , m ( 1 ≤ n ≤ 150 n,m\ (1 \leq n\leq 150 n,m (1≤n≤150, 1 ≤ m ≤ 5000 ) 1 \leq m \leq 5000) 1≤m≤5000),分别表示有 n n n 个城市,总共 m m m 条铁路。
以下 m m m 行,每行两个整数 a , b a, b a,b,表示城市 a a a 和城市 b b b 之间有铁路直接连接。
输出格式
输出有若干行。
每行包含两个数字 a , b a,b a,b,其中 a < b a<b a<b,表示 ⟨ a , b ⟩ \lang a,b\rang ⟨a,b⟩ 是 key road。
请注意:输出时,所有的数对 ⟨ a , b ⟩ \lang a,b\rang ⟨a,b⟩ 必须按照 a a a 从小到大排序输出;如果 a a a 相同,则根据 b b b 从小到大排序。
样例 #1
样例输入 #1
6 6
1 2
2 3
2 4
3 5
4 5
5 6
样例输出 #1
1 2
5 6
思路
你肯定是炸到桥边才使其不连通。
- 只不过这道题是要记录路径,我们就在代码注释处写就行了。
代码
//缩点
//桥
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N = 1e6+10,M = 4e6+10;
int e[M],ne[M],w[M],h[N],idx;
// bool is_bridge[N];
int dfn[N],low[N];
int scc_cnt,id[N];
int stk[N],tm,top;
int n,m;
int din[N];
struct E{
int x,y;
};
vector<E>ans;
bool cmp(E a,E b){
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void targin(int u,int v){
low[u]=dfn[u]=++tm;
// stk[top]=u;
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(!dfn[j]){
targin(j,i);
low[u]=min(low[u],low[j]);
//j到不了u,是桥的判断:走过了就不能在回来了:)
if(dfn[u]<low[j]){
ans.push_back({u,j});
// is_bridge[i]=is_bridge[i^1]=true;
}
}else if(i!=(v^1)){//i不是j反向边,将j进行更新
low[u]=min(low[u],dfn[j]);
}
}
// if(dfn[u]==low[u]){
// scc_cnt++;
// int y;
// do{
// y=stk[top--];
// id[y]=scc_cnt;
// }while(y!=u);
// }
}
int main(){
cin>>n>>m;
memset(h,-1,sizeof h);
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
targin(1,-1);
sort(ans.begin(),ans.end(),cmp);
for(int i=0;i<ans.size();i++){
cout<<ans[i].x<<" "<<ans[i].y<<endl;
}
return 0;
}