codeforces131D. Subway(DFS+BFS)

本文介绍了一种算法,用于解决地铁系统中寻找每个站点到环路最近距离的问题。通过分析度数为1的站点并逐步移除,最终确定环路位置,再通过深度优先搜索计算所有站点到环路的距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                D. Subway

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

A subway scheme, classic for all Berland cities is represented by a set of n stations connected by n passages, each of which connects exactly two stations and does not pass through any others. Besides, in the classic scheme one can get from any station to any other one along the passages. The passages can be used to move in both directions. Between each pair of stations there is no more than one passage.

Berland mathematicians have recently proved a theorem that states that any classic scheme has a ringroad. There can be only one ringroad. In other words, in any classic scheme one can find the only scheme consisting of stations (where any two neighbouring ones are linked by a passage) and this cycle doesn't contain any station more than once.

This invention had a powerful social impact as now the stations could be compared according to their distance from the ringroad. For example, a citizen could say "I live in three passages from the ringroad" and another one could reply "you loser, I live in one passage from the ringroad". The Internet soon got filled with applications that promised to count the distance from the station to the ringroad (send a text message to a short number...).

The Berland government decided to put an end to these disturbances and start to control the situation. You are requested to write a program that can determine the remoteness from the ringroad for each station by the city subway scheme.

Input

The first line contains an integer n (3 ≤ n ≤ 3000), n is the number of stations (and trains at the same time) in the subway scheme. Then nlines contain descriptions of the trains, one per line. Each line contains a pair of integers xi, yi (1 ≤ xi, yi ≤ n) and represents the presence of a passage from station xi to station yi. The stations are numbered from 1 to n in an arbitrary order. It is guaranteed that xi ≠ yi and that no pair of stations contain more than one passage. The passages can be used to travel both ways. It is guaranteed that the given description represents a classic subway scheme.

Output

Print n numbers. Separate the numbers by spaces, the i-th one should be equal to the distance of the i-th station from the ringroad. For the ringroad stations print number 0.

Examples

input

Copy

4
1 3
4 3
4 2
1 2

output

Copy

0 0 0 0 

input

Copy

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

output

Copy

0 0 0 1 1 2 

 

一、原题地址

点我传送

 

二、大致题意

给出n表示有n个点,然后再给出n条双向的边,询问图上的每个点点到达环的最小距离是多少。

 

三、大致思路

n个点n条边,所以肯定就一个环。

所以理论上只需要找到那个环,环上的点答案都是0,然后再从环上的点向外搜索就可以跑出环外面点的答案了。

如何标记出环呢,首先读入后度数为1的点肯定不在环上,所以我们可以从它们出发,去掉它们度数的影响(即与它相连的点度数减1 ),如果此时又出现了度为1的点,那么我们就再把这个新的点重复上面的操作。

这样做的正确性:首先环上的点一开始不会被加入到搜索的队列中,那么它们度数的减少就只能靠周围的点传递过来,但是即使传递过来使得环上的点度数减少,这个减少后的值也不会低于2,所以这些点永远不会进入队列(即永远不会被更新)。

 

四、丑陋代码

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<stack>
#include<bitset>
using namespace std;
#define PI 3.14159265
const int inf=0x3f3f3f3f;
typedef long long LL;
typedef unsigned long long ull;


int n,ind[3005],ans[3005];
vector<int>e[3005];
bool col[3005];

void read()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)ind[i]=0;
    for(int i=1;i<=n;i++)
    {
        int u,v;
        scanf("%d %d",&u,&v);
        e[u].push_back(v);
        e[v].push_back(u);
        ind[u]++;ind[v]++;
    }
}

void Color()
{
    queue<int>q;
    for(int i=1;i<=n;i++)
    {
        col[i]=false;
        if(ind[i]==1)
        {
            q.push(i);col[i]=true;
        }
    }

    while(!q.empty())
    {
        int t=q.front();q.pop();
        for(int i=0;i<e[t].size();i++)
        {
            int to =e[t][i];
            if(!col[to])
            {
                ind[to]--;
                if(ind[to]<=1)
                {
                    q.push(to);col[to]=true;
                }
            }
        }
    }
}

void DFS(int nx,int pr,int step)
{
    ans[nx]=step;
    for(int i=0;i<e[nx].size();i++)
    {
        int to =e[nx][i];
        if(to!=pr&&col[to])
        {
            DFS(to,nx,step+1);
        }
    }
}

int main()
{
    read();
    Color();
    for(int i=1;i<=n;i++)
    {
        if(!col[i])DFS(i,-1,0);
    }
    for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值