题目地址:http://codeforces.com/problemset/problem/131/D
思路:寻找环。首先将度数为1的节点入队,将与度数为1的节点的度数减一。将度数小于2的节点入队并标记,最后没有被标记的节点就是组成环的节点。
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const int maxn=3e3+50;
int n;
queue<int> q;
vector<int> g[maxn];
int d[maxn],v[maxn];
int dist[maxn],V[maxn];
void mindist(int s)
{
memset(V,0,sizeof(V));
while(!q.empty()) q.pop();
q.push(s),V[s]=1,dist[s]=0;
while(!q.empty())
{
int now=q.front();
q.pop(),V[now]=0;
for(int i=0; i<g[now].size(); i++)
{
int nt=g[now][i];
if(dist[nt]>dist[now]+1)
{
dist[nt]=dist[now]+1;
if(!V[nt]);
{
V[nt]=1;
q.push(nt);
}
}
}
}
}
void solve()
{
for(int i=1; i<=n; i++)
if(d[i]==1)
{
q.push(i);
v[i]=1;
}
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=0; i<g[now].size(); i++)
{
int nt=g[now][i];
d[nt]--;
if(d[nt]<2&&!v[nt])
{
v[nt]=1;
q.push(nt);
}
}
}
//cout<<"flag"<<endl;
memset(dist,0x3f3f3f3f,sizeof(dist));
for(int i=1; i<=n; i++)
if(!v[i]) mindist(i);
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif // debug
scanf("%d",&n);
for(int i=0; i<n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
d[x]++,d[y]++;
g[x].push_back(y);
g[y].push_back(x);
}
solve();
for(int i=1; i<n; i++)
printf("%d ",dist[i]);
printf("%d\n",dist[n]);
return 0;
}