• codeforces 131D Subway


    题意



    给你一个无向图,n个点n条边,保证图连通,并且有且只有有一个环,求出每个点距离环的距离


    分析:第一次写这样的问题,之前听说过环缩点但是不知道具体算法是什么样子的。

    大体算法是两次bfs,第一次找出属于环的点,第二次是将环向外bfs。

    第一次bfs:将所有度为1的点加入队列中(因为度为1的点必定不是环里的点)进行bfs,如果遇到度>=3的点,先将这个点的度剪去1,直到这个点的度为2的时候才将其加入队列,并且标记vis 。

    因为如果的环上的点,度不可能被减为2。环内部的点度虽然为2但是不会被访问到。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    using namespace std;
    #define MAX_N        3005
    #define MAX_M         10007
    struct ed
    {
        int to;
        int next; 
    }edge[MAX_M];
    int n;
    int stu[MAX_N];
    int col = 0;
    int ednum[MAX_N];
    bool vis[MAX_N];
    void addedge(int u , int v)
    {
        edge[col].to = v;
        edge[col].next = stu[u];
        stu[u] = col++;
    }
    void bfs(){
        queue<int> que;
        for (int i = 1; i <= n ; ++i)
        {
            if(ednum[i] == 1){
                que.push(i);
                vis[i] = true;
            }
        }
        while(!que.empty())
        {
            int tem =  que.front();
            que.pop();
            for (int i = stu[tem]; i !=-1 ; i = edge[i].next)
            {
                if(vis[edge[i].to])
                    continue;
                if(ednum[edge[i].to]==2)
                {
                    que.push(edge[i].to);
                    vis[edge[i].to] = true;
                }
                else
                    ednum[edge[i].to]--;
            }
        }
    }
    int ans[MAX_N];
    void bfs2()
    {
        queue<int> que;
        for (int i = 1; i <= n ; ++i)
        {
            if(!vis[i])
                que.push(i);
        }
        while(!que.empty())
        {
            int tem =  que.front();
            que.pop();
            for (int i = stu[tem]; i !=-1 ; i = edge[i].next)
            {
                if(!vis[edge[i].to])
                    continue;
                vis[edge[i].to] = false;
                que.push(edge[i].to);
                ans[edge[i].to] = ans[tem]+1;
            }
        }
    }
    int main(int argc, char const *argv[])
    {
        memset(stu,-1,sizeof(stu));
        scanf("%d",&n);
        int fir, las ;
        for (int i = 0; i < n; ++i)
        {
            scanf("%d%d",&fir,&las);
            addedge(fir,las);
            addedge(las,fir);
            ednum[fir]++;
            ednum[las]++;
        }
        bfs();
        bfs2();
        printf("%d",ans[1] );
        for (int i = 2; i <= n; ++i)
        {
            printf(" %d",ans[i] );
        }
        printf("\n");
    
        return 0;
    }
  • 相关阅读:
    JavaScript indexOf() 方法 和 lastIndexOf() 方法
    JS处理四舍五入函数 toFixed(n)(可取小数点后n位)
    animate支持的css属性
    jquery 停止动画 stop的几种用法
    js动态创建style节点(js文件中添加css)
    在CSS中定义a:link、a:visited、a:hover、a:active顺序
    网站设计如何适合用户的操作习惯?
    mongoDB入门必读
    堆栈简析
    单例模式
  • 原文地址:https://www.cnblogs.com/miamiao/p/6858654.html
Copyright © 2020-2023  润新知