zoukankan      html  css  js  c++  java
  • COGS 8. 备用交换机

    8. 备用交换机

    【问题描述】

    n个城市之间有通讯网络,每个城市都有通讯交换机,直接或间接与其它城市连接。因电子设备容易损坏,需给通讯点配备备用交换机。但备用交换机数量有限,不能全部配备,只能给部分重要城市配置。于是规定:如果某个城市由于交换机损坏,不仅本城市通讯中断,还造成其它城市通讯中断,则配备备用交换机。请你根据城市线路情况,计算需配备备用交换机的城市个数,及需配备备用交换机城市的编号。
    【输入格式】
    输入文件有若干行
    第一行,一个整数n,表示共有n个城市(2<=n<=100)
    下面有若干行,每行2个数a、b,a、b是城市编号,表示a与b之间有直接通讯线路。
    【输出格式】
    输出文件有若干行
    第一行,1个整数m,表示需m个备用交换机,下面有m行,每行有一个整数,表示需配备交换机的城市编号,输出顺序按编号由小到大。如果没有城市需配备备用交换机则输出0。
    【输入输出样例】

    输入文件名: gd.in

     

    7

    1 2

    2 3

    2 4

    3 4

    4 5

    4 6

    4 7

    5 6

    6 7

     

     

    输出文件名:gd.out

     

    2

    2

    4

    割点个数,if_必须放到函数里

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 1000000
    int n,m,x,y,tot,tim,dfn[maxn],low[maxn],head[maxn],ans;
    int cut_edge[maxn],cut_point[maxn];
    bool vis[maxn];
    struct Edge{
        int next,to,from;
    }edge[maxn];
    
    void add(int x,int y)
    {
        edge[tot].to=y;
        edge[tot].next=head[x];
        head[x]=tot;
        tot++;
    }
    
    void tarjan(int now,int pre)
    {
        int sum=0;
        bool if_=false;
        vis[now]=true;
        dfn[now]=low[now]=++tim;
        for(int i=head[now];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if((i^1)!=pre)
            {
                if(!vis[v])
                {
                    sum++;
                    tarjan(v,i);
                    if(low[v]>dfn[now]) cut_edge[i/2]=1;
                    if(low[v]>=dfn[now]) if_=true;
                    low[now]=min(low[now],low[v]);
                }
                else low[now]=min(low[now],dfn[v]);
            }
        }
        if(pre==-1) 
        {
            if(sum>1)
            cut_point[now]=1;
        }
        else if(if_==1) cut_point[now]=1;
        return ;
    }
    int main()
    {
    //    freopen("gd.in","r",stdin);
    //    freopen("gd.out","w",stdout);
        scanf("%d",&n);
        memset(head,-1,sizeof(head));
        while(scanf("%d%d",&x,&y)!=EOF) add(x,y),add(y,x);
        for(int i=1;i<=n;i++)
            if(!vis[i]) tarjan(i,-1);
        for(int i=1;i<=n;i++)
            if(cut_point[i]) ans++;
        printf("%d
    ",ans);
        for(int i=1;i<=n;i++) if(cut_point[i]) printf("%d
    ",i);
        return 0;
    }
  • 相关阅读:
    八.正文处理命令及tar命令
    七.用户.群组及权限的深入讨论
    六.用户.群组和权限
    五.目录,文件的浏览,管理和维护
    四.linux 命令及获取帮助
    计算机的基础知识
    三.linux基本的50条命令
    二.Python的基本数据类型及常用功能
    一.编码的转换和基本的算法
    Linux开机自动挂载Windows分区
  • 原文地址:https://www.cnblogs.com/chen74123/p/7425158.html
Copyright © 2011-2022 走看看