• 炸铁路


    【题目描述】:

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

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

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

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

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

    【输入描述】:

    第一行n,m,分别表示有n个城市,总共m条铁路。

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

    【输出描述】:

    输出有若干行。

    每行包含两个数字a,b(不保证a是key road。

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

    【样例输入】:

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

    【样例输出】:

    1 2
    5 6

    【时间限制、数据范围及描述】:

    时间:1s 空间:128M

    1<=n<=10000, 1<=m<=100000

    洛谷上的原题,但良心贾把数据范围改掉了,直接卡掉除Tarjan之外的任何非正解(本人已试过DFS,并查集,SPFA,统统被卡了3个点)······

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    #define  N 500005
    
    using namespace std;
    
    bool c[N];
    
    int n,m,x,y,s,tot,tim;
    
    int dfn[N],low[N],head[N];
    
    int read(){
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    struct edge{
        int from,to,next;
    }edge[N];
    
    void add(int x,int y){
        tot++;
        edge[tot].to=y;
        edge[tot].from=x;
        edge[tot].next=head[x];
        head[x]=tot;
    }
    
    struct nn{
        int x,y;
    }q[N];
    
    int cmp(nn a,nn b){
        if(a.x!=b.x){
            return a.x<b.x;
        }
        return a.y<b.y;
    }
    
    void tarjan(int now,int pre){
        dfn[now]=low[now]=++tim;
        for(int i=head[now];i;i=edge[i].next){
            int t=edge[i].to;
            if((1^i)==pre){
                continue;
            }
            if(!dfn[t]){
                tarjan(t,i);
                low[now]=min(low[now],low[t]);
                if(dfn[now]<low[t]){
                    c[i>>1]=true;
                }
            }
            else{
                low[now]=min(low[now],dfn[t]);
            }
        }
    }
    
    int main(){
        n=read();
        m=read();
        tot=1;
        for(int i=1;i<=m;i++){
            x=read();
            y=read();
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i]) tarjan(i,-1);
        }
        for(int i=1;i<=m;i++){
            if(c[i]) {
                ++s;
                q[s].x=edge[i<<1].from;
                q[s].y=edge[i<<1].to;
                if(q[s].x>q[s].y){
                    swap(q[s].x,q[s].y);
                }
            }
        }
        sort(q+1,q+1+s,cmp);
        for(int i=1;i<=s;i++){
            printf("%d %d
    ",q[i].x,q[i].y);
        }
        return 0;
    }
  • 相关阅读:
    string的erase函数和find、find_first_of函数
    strtok和strtok_r
    Linux添加硬盘 挂载硬盘(附 Linux磁盘挂载和mount共享 带图)
    linux下访问中文目录文件
    用yield写协程实现生产者消费者
    用进程池和线程池实现高并发服务器
    python自带线程池
    python自带进程池
    模拟线程池代码
    面向对象的多次调用线程(含参版)
  • 原文地址:https://www.cnblogs.com/hrj1/p/11154740.html
Copyright © 2020-2023  润新知