codeforces131D

CodeForces-131D地铁方案解析
本文详细解析了CodeForces-131D题目的地铁方案问题,介绍了如何通过O(n)BFS查找环以及n^2 DFS解决经典Berland城市地铁系统中的环路和距离计算问题。

Subway

 CodeForces - 131D 

A subway scheme, classic for all Berland cities is represented by a set of nstations 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 n lines 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
4
1 3
4 3
4 2
1 2
Output
0 0 0 0 
Input
6
1 2
3 4
6 4
2 3
1 3
3 5
Output
0 0 0 1 1 2 

sol:这个数据范围实在是太友好了,O(n)bfs找环,n2dfs水过无压力,不知道(我猜)有更好的做法(树剖)可以nlogn
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=3005,M=6005,inf=0x3f3f3f3f;
int n;
namespace Pic
{
    int tot=0,Next[M],to[M],head[N],Deg[N];
    
    inline void add(int x,int y);
    inline void dfs(int x,int fa);
    inline void Solve();
    
    inline void add(int x,int y)
    {
        Next[++tot]=head[x];
        to[tot]=y;
        head[x]=tot;
        Deg[y]++;
    }
    bool Vis[N];
    inline void bfs()
    {
        int i;
        queue<int>Queue;
        for(i=1;i<=n;i++) if(Deg[i]==1)
        {
            Queue.push(i);
            Vis[i]=1;
        }
        while(!Queue.empty())
        {
            int x=Queue.front(); Queue.pop();
            for(i=head[x];i;i=Next[i]) if(!Vis[to[i]])
            {
                Deg[to[i]]--;
                if(Deg[to[i]]<2)
                {
                    Vis[to[i]]=1;
                    Queue.push(to[i]);
                }
            }
        }
    }
    int Ans[N];
    bool Huan[N];
    inline int dfs(int x,int fa,int Dis)
    {
        if(Huan[x]) return Dis;
        int i,res=inf;
        for(i=head[x];i;i=Next[i]) if(to[i]!=fa)
        {
            res=min(res,dfs(to[i],x,Dis+1));
        }
        return res;
    }
    inline void Solve()
    {
        int i;
        bfs();
        for(i=1;i<=n;i++) if(!Vis[i]) Huan[i]=1;
        for(i=1;i<=n;i++) Ans[i]=dfs(i,0,0);
        for(i=1;i<=n;i++) W(Ans[i]);
    }
}
int main()
{
    int i;
    R(n);
    for(i=1;i<=n;i++)
    {
        int x,y; R(x); R(y);
        Pic::add(x,y); Pic::add(y,x);
    }
    Pic::Solve();
    return 0;
}
/*
Input
4
1 3
4 3
4 2
1 2
Output
0 0 0 0 

Input
6
1 2
3 4
6 4
2 3
1 3
3 5
Output
0 0 0 1 1 2 
*/
View Code

 

 

转载于:https://www.cnblogs.com/gaojunonly1/p/10765629.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值