洛谷 P1656 炸铁路

题目描述

因为某国被某红色政权残酷的高压暴力统治。美国派出将军uim,对该国进行战略性措施,以解救涂炭的生灵。

该国有n个城市,这些城市以铁路相连。任意两个城市都可以通过铁路直接或者间接到达。

uim发现有些铁路被毁坏之后,某两个城市无法互相通过铁路到达。这样的铁路就被称为key road。

uim为了尽快使该国的物流系统瘫痪,希望炸毁铁路,以达到存在某两个城市无法互相通过铁路到达的效果。

然而,只有一发炮弹(美国国会不给钱了)。所以,他能轰炸哪一条铁路呢?

输入输出格式

输入格式:
第一行n,m(1<=n<=150, 1<=m<=5000),分别表示有n个城市,总共m条铁路。

以下m行,每行两个整数a, b,表示城市a和城市b之间有铁路直接连接。

输出格式:
输出有若干行。

每行包含两个数字a,b(a < b),表示 < a,b > 是key road。

请注意:输出时,所有的数对 < a,b > 必须按照a从小到大排序输出;如果a相同,则根据b从小到大排序。

输入输出样例

输入样例1:
6 6
1 2
2 3
2 4
3 5
4 5
5 6
输出样例1
1 2
5 6

求割边模板题直接用Tarjan
(我把我博客里tarjan求割边的模板代码改改拿过来了)

code:

#include
#include
#include
using namespace std;

const int MAX=1000010;
int n,m,cnt,sum;
int head[MAX],low[MAX],dfn[MAX],cedge[MAX];

struct edg{
    int to,next,from;
}edge[MAX];

void add(int x,int y){
    edge[++cnt].next=head[x];
    edge[cnt].from=x,edge[cnt].to=y;
    head[x]=cnt;
}

void cutedge(int u,int f){
    dfn[u]=low[u]=++cnt;
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(!dfn[v]){
            cutedge(v,u);
            low[u]=min(low[u],low[v]);
            if(dfn[u]else if(v!=f) low[u]=min(low[u],dfn[v]);
    }
}

bool cmp(int a,int b){
    if(edge[a].from==edge[b].from) return edge[a].toreturn edge[a].fromvoid find_cutedge(){
    for(int i=1;i<=n;i++) if(!dfn[i]) cutedge(i,0);
    sort(cedge+1,cedge+sum+1,cmp);
    for(int i=1;i<=sum;i++) printf("%d %d\n",edge[cedge[i]].from,edge[cedge[i]].to); 
}

int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%d %d",&a,&b);
        add(a,b);
        add(b,a);
    }
    find_cutedge();
    return 0;
}

你可能感兴趣的:(图论-tarjan)