Codeforces Beta Round #95 (Div. 2) D. Subway(环最短路)

来源:互联网 发布:迪蒙火花机编程实例 编辑:程序博客网 时间:2024/06/07 12:23

题目地址:http://codeforces.com/problemset/problem/131/D

思路:寻找环。首先将度数为1的节点入队,将与度数为1的节点的度数减一。将度数小于2的节点入队并标记,最后没有被标记的节点就是组成环的节点。

#include<cstdio>#include<queue>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#define debuusing 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;}


0 0