• bridge


    Time limit : 2sec / Memory limit : 256MB

    Score : 300 points

    Problem Statement

    You are given an undirected connected graph with N vertices and M edges that does not contain self-loops and double edges.
    The i-th edge (1≤iM) connects Vertex ai and Vertex bi.

    An edge whose removal disconnects the graph is called a bridge.
    Find the number of the edges that are bridges among the M edges.

    Notes

    • self-loop is an edge i such that ai=bi (1≤iM).
    • Double edges are a pair of edges i,j such that ai=aj and bi=bj (1≤i<jM).
    • An undirected graph is said to be connected when there exists a path between every pair of vertices.

    Constraints

    • 2≤N≤50
    • N−1≤Mmin(N(N−1)⁄2,50)
    • 1≤ai<biN
    • The given graph does not contain self-loops and double edges.
    • The given graph is connected.

    Input

    Input is given from Standard Input in the following format:

    N M  
    a1 b1  
    a2 b2
    :  
    aM bM
    

    Output

    Print the number of the edges that are bridges among the M edges.


    Sample Input 1

    Copy
    7 7
    1 3
    2 7
    3 4
    4 5
    4 6
    5 6
    6 7
    

    Sample Output 1

    Copy
    4
    

    The figure below shows the given graph:

    570677a9809fd7a5b63bff11e5d9bf79.png

    The edges shown in red are bridges. There are four of them.


    Sample Input 2

    Copy
    3 3
    1 2
    1 3
    2 3
    

    Sample Output 2

    Copy
    0
    

    It is possible that there is no bridge.


    Sample Input 3

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

    Sample Output 3

    Copy
    5
    

    It is possible that every edge is a bridge.

    题目意思:判断给定的图像中的不属于环的边有几条;

    主要思路:1.遍历判断每一条边中的一点能否到达另一点

    代码1:每次判断每条边时,都创建一个地图副本,把每次走过的边都消除,

    比较容易理解,但是遇到多的数据的时候,会很慢;

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include <map>
    #include <string.h>
     
    using namespace std;
     
    struct S
    {
        int Map[55][55];
    };
     
    int N,M;
    int a[55],b[55],Map[55][55];
     
    bool dfs(S s,int l,int r)
    {
       // cout<<" -> "<<l<<" "<<r<<endl;
        int falg = false;
        for(int i = 1;i<=N;i++){
            if((l>i&&s.Map[i][l])||(l<i&&s.Map[l][i])){
                if(l>i) s.Map[i][l] = 0;
                else s.Map[l][i] = 0;
                if(i==r)
                    return true;
                if(dfs(s,i,r))
                    return true;
            }
        }
        return falg;
    }
     
    int main()
    {
        cin>>N>>M;
        for(int i = 1;i <=M; i++){
            cin>>a[i]>>b[i];
            if(a[i]>b[i])
                Map[b[i]][a[i]] = 1;
            else
                Map[a[i]][b[i]] = 1;
         }
     
         int sum = 0;
        for(int i = 1;i<=M;i++){
            S s;
            memcpy(s.Map,Map,sizeof(Map));
            if(a[i]>b[i])
                s.Map[b[i]][a[i]] = 0;
            else
                s.Map[a[i]][b[i]] = 0;
            if(!dfs(s,a[i],b[i]))
                sum++;
           // cout<<a[i]<<" "<<b[i]<<" <-> "<<sum<<endl;
        }
     
        cout<<sum<<endl;
     
        return 0;
    }
    代码1

    代码2;相当与上面代码的改进,用一个临时数组来储存每次经过的头

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    #include <set>
    #include <queue>
    #include <stack>
    #include <map>
    #include <stdlib.h>
    using namespace std;
    
    int N,M;
    int a[55],b[55],Map[55][55];
    int visit[55];
    
    bool dfs(int l,int r,int num)
    {
        int j ;
        if(l==r||Map[l][r]==1)
            return true;
        visit[num] = l;
        for(int i = 1;i<=M;i++){
            for(j=0;j<num;j++){
                if(visit[j]==i)
                    break;
            }
            if(j<num&&visit[j]==i) continue;
            if(Map[l][i]!=1) continue;
            if(dfs(i,r,num+1))
                return true;
        }
    
        return false;
    }
    
    int main(){
        cin>>N>>M;
        for(int i = 1;i<=M;i++){
            cin>>a[i]>>b[i];
            Map[a[i]][b[i]] = Map[b[i]][a[i]] = 1;
        }
    
        int sum = 0;
        for(int i = 1;i<=M;i++){
            memset(visit,0,sizeof(visit));
            Map[a[i]][b[i]] = 0;
            if(!dfs(a[i],b[i],0))
                sum++;
            Map[a[i]][b[i]] = 1;
        }
        cout<<sum<<endl;
        return 0;
    }
    代码2

    代码3:使用了Floyd算法,来判断俩点之间的连通性; 

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    #include <set>
    #include <queue>
    #include <stack>
    #include <map>
    #include <stdlib.h>
    using namespace std;
     
     
    #define inf (int)(1e9)
     
    int main(){
        int N, M, i, j, k, l, ans = 0;
        cin>>N>>M;
        int a[55],b[55],e[55][55];
        for(i = 0; i < M; i++){
            cin>>a[i]>>b[i];
            a[i]--;
            b[i]--;
        }
        for(l = 0; l < M; l++){
            for(int i = 0;i<N;i++)
                for(int j = 0;j<N;j++)
                    e[i][j] = inf;
            for(i = 0; i < M; i++){
                if(i != l){
                    e[a[i]][b[i]] = 1;
                    e[b[i]][a[i]] = 1;
                }
            }
            for(k = 0; k < N; k++){
                for(i = 0; i < N; i++){
                    for(j = 0; j < N; j++){
                        if(e[i][j] > e[i][k] + e[k][j]){
                            e[i][j] = e[i][k] + e[k][j];
                        }
                    }
                }
            }
            if(e[a[l]][b[l]] == inf){
                ans++;
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code

    代码4:储存每个结点连接的边的个数,每次都值为1的点出发,当前结点的值和相邻的点的值都减一;

    当没有值为一的点时结束;过程中值为1的点的个数就是不循环的边的个数;

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    #include <set>
    #include <queue>
    #include <stack>
    #include <map>
    #include <stdlib.h>
    using namespace std;
     
    int N,M;
    int Map[55][55],a[55],b[55];
    int visit[55];
     
    int main(){
     
        cin>>N>>M;
        for(int i = 1;i<=M;i++){
            cin>>a[i]>>b[i];
            visit[a[i]]++;
            visit[b[i]]++;
            Map[a[i]][b[i]] = Map[b[i]][a[i]] = 1;
        }
        int sum = 0;
        int xi;
        bool falg = true;
        while(1){
            falg = true;
            for(int i = 1;i<=N;i++){
                if(visit[i]==1){
                        sum++;
                    xi = i;
                    falg = false;
                    visit[i]--;
                    break;
                }
            }
            if(falg) break;
            for(int i = 1;i<=N;i++){
                if(Map[xi][i]==1)
                    visit[i]--;
            }
        }
       
     
        cout<<sum<<endl;
     
        return 0;
    }
    Submission
    代码4
  • 相关阅读:
    谈谈系统
    快速发展的Swift是否将淘汰Objective-C?
    XCode环境变量及路径设置
    Windows server2008 搭建ASP接口访问连接oracle数据库全过程记录--备用
    Swift2.0新特性--文章过时重置
    【XCode7+iOS9】http网路连接请求、MKPinAnnotationView自定义图片和BitCode相关错误--备用
    移动App双周版本迭代策略
    ti8168平台的tiler memory
    图像处理之二维码生成-qr
    大数据之网络爬虫-一个简单的多线程爬虫
  • 原文地址:https://www.cnblogs.com/a2985812043/p/7671144.html
Copyright © 2020-2023  润新知