zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    POJ3159 Candies —— 差分约束 spfa
    POJ1511 Invitation Cards —— 最短路spfa
    POJ1860 Currency Exchange —— spfa求正环
    POJ3259 Wormholes —— spfa求负环
    POJ3660 Cow Contest —— Floyd 传递闭包
    POJ3268 Silver Cow Party —— 最短路
    POJ1797 Heavy Transportation —— 最短路变形
    POJ2253 Frogger —— 最短路变形
    POJ1759 Garland —— 二分
    POJ3685 Matrix —— 二分
  • 原文地址:https://www.cnblogs.com/miamiao/p/6858654.html
Copyright © 2011-2022 走看看