[最大环+缩点+BFS]codeforces Round 95 Div2
http://www.codeforces.com/problemset/problem/131/D
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=3000+1;
const int maxint=2147483647;
vi G,next,dest,timee,path;
vb vis;
void addd(int a,int b){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
}
int ans,cycf,cyct;
int n;
void init(){
scanf("%d",&n);
G.assign(n+1,-1);
timee.assign(n+1,0);
vis.assign(n+1,false);
path.assign(n+1,-1);
ans=-1;
re1(u,n){
int a,b;
scanf("%d%d",&a,&b);
addd(a,b);
addd(b,a);
}
}
void dfs(int s,int t){
vis[s]=true;
timee[s]=t;
for(int i=G[s];i!=-1;i=next[i]){
int v=dest[i];
if(!vis[v]){
dfs(v,t+1);
path[v]=s;
}else{
int tmp=timee[v]-timee[s];
if(ans<tmp){
ans=tmp;
cycf=v;
cyct=s;
}
}
}
}
vi G2,next2,dest2,id;
void pp(int from,int to){
if(to==from){
id[from]=from;
}
else{
pp(from,path[to]);
id[to]=from;
}
}
set<pair<int,int> > S;
void makeG(){
G2.assign(n+1,-1);
id.assign(n+1,0);
S.clear();
}
void addG2(int a,int b){
next2.push_back(G2[a]);
G2[a] = SIZE(next2)-1;
dest2.push_back(b);
}
int mmain(){
init();
dfs(1,0);
makeG();
re1(u,n){
id[u]=u;
}
pp(cyct,cycf);
re1(u,n){
for(int i=G[u];i!=-1;i=next[i]){
int v=dest[i];
pair<int,int> p=make_pair(id[u],id[v]);
if(p.first==p.second)
continue;
set<pair<int,int> >::iterator it=S.find(p);
if(it==S.end()){
S.insert(p);
addG2(p.first,p.second);
}
}
}
vi final_ans(n+1,0),distt(n+1,0);
int Q[maxnum+1];
int head=-1,rear=0;
Q[rear++]=cyct;
distt[cyct]=1;
final_ans[cyct]=distt[cyct]-1;
while(head+1<rear){
int tnode=Q[++head];
for(int i=G2[tnode];i!=-1;i=next2[i]){
int v=dest2[i];
if(!distt[v]){
Q[rear++]=v;
distt[v]=distt[tnode]+1;
final_ans[v]=distt[v]-1;
}
}
}
re1(u,n){
printf("%d ",final_ans[u]);
}
puts("");
}
#define codeforces CODEFORCES
//#define INPUT CODEFORCES_FILE
//#define MANY_TEST CODEFORCES_MANY_TEST
const int MANY_TESST=2;
int main(){
#ifdef codeforces
#ifdef INPUT
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain();
}
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=3000+1;
const int maxint=2147483647;
vi G,next,dest,timee,path;
vb vis;
void addd(int a,int b){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
}
int ans,cycf,cyct;
int n;
void init(){
scanf("%d",&n);
G.assign(n+1,-1);
timee.assign(n+1,0);
vis.assign(n+1,false);
path.assign(n+1,-1);
ans=-1;
re1(u,n){
int a,b;
scanf("%d%d",&a,&b);
addd(a,b);
addd(b,a);
}
}
void dfs(int s,int t){
vis[s]=true;
timee[s]=t;
for(int i=G[s];i!=-1;i=next[i]){
int v=dest[i];
if(!vis[v]){
dfs(v,t+1);
path[v]=s;
}else{
int tmp=timee[v]-timee[s];
if(ans<tmp){
ans=tmp;
cycf=v;
cyct=s;
}
}
}
}
vi G2,next2,dest2,id;
void pp(int from,int to){
if(to==from){
id[from]=from;
}
else{
pp(from,path[to]);
id[to]=from;
}
}
set<pair<int,int> > S;
void makeG(){
G2.assign(n+1,-1);
id.assign(n+1,0);
S.clear();
}
void addG2(int a,int b){
next2.push_back(G2[a]);
G2[a] = SIZE(next2)-1;
dest2.push_back(b);
}
int mmain(){
init();
dfs(1,0);
makeG();
re1(u,n){
id[u]=u;
}
pp(cyct,cycf);
re1(u,n){
for(int i=G[u];i!=-1;i=next[i]){
int v=dest[i];
pair<int,int> p=make_pair(id[u],id[v]);
if(p.first==p.second)
continue;
set<pair<int,int> >::iterator it=S.find(p);
if(it==S.end()){
S.insert(p);
addG2(p.first,p.second);
}
}
}
vi final_ans(n+1,0),distt(n+1,0);
int Q[maxnum+1];
int head=-1,rear=0;
Q[rear++]=cyct;
distt[cyct]=1;
final_ans[cyct]=distt[cyct]-1;
while(head+1<rear){
int tnode=Q[++head];
for(int i=G2[tnode];i!=-1;i=next2[i]){
int v=dest2[i];
if(!distt[v]){
Q[rear++]=v;
distt[v]=distt[tnode]+1;
final_ans[v]=distt[v]-1;
}
}
}
re1(u,n){
printf("%d ",final_ans[u]);
}
puts("");
}
#define codeforces CODEFORCES
//#define INPUT CODEFORCES_FILE
//#define MANY_TEST CODEFORCES_MANY_TEST
const int MANY_TESST=2;
int main(){
#ifdef codeforces
#ifdef INPUT
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain();
}