CodeForces 689 B. Mike and Shortcuts(SPFA)

来源:互联网 发布:淘宝网做生意 编辑:程序博客网 时间:2024/06/05 23:03

Description
n个点,任意两点距离为其编号差的绝对值,同时有n条捷径,i到a[i]之间距离为1,问点1到点i的最短距离
Input
第一行一整数n表示点数,之后n个整数a[i] (1<=n<=200000,i<=a[i]<=n,a[i]<=a[i+1])
Output
输出n个数,第i个数表示点1到点i的最短距离
Sample Input
3
2 2 3
Sample Output
0 1 2
Solution
建完图跑一边最短路即可,注意不需要任意两点都建图,只建相邻两点即可
Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 222222struct edge{    int to,next;    int cost;}g[maxn*3];int head[maxn],tol;int dis[maxn];//所有点到起点的最短距离void init()//初始化 {    memset(head,-1,sizeof(head));    tol=0;}void add(int u,int v,int c)//单向边,从u到v,权值为c {    g[tol].cost=c;    g[tol].to=v;    g[tol].next=head[u];    head[u]=tol++;}void spfa(int s)//单源最短路,s是起点{    bool vis[maxn];    memset(vis,false,sizeof(vis));    queue<int>que;    for(int i=0;i<maxn;i++)        dis[i]=INF;    dis[s]=0;    vis[s]=true;    que.push(s);    while(!que.empty())    {        int u=que.front();        que.pop();        vis[u]=false;        for(int i=head[u];i!=-1;i=g[i].next)        {            int v=g[i].to;            int c=g[i].cost;            if(dis[v]>dis[u]+c)            {                dis[v]=dis[u]+c;                if(!vis[v])                {                    vis[v]=true;                    que.push(v);                }            }        }    }}int main(){    int n;    while(~scanf("%d",&n))    {        init();        for(int i=1;i<n;i++)add(i,i+1,1),add(i+1,i,1);        for(int i=1;i<=n;i++)        {            int a;            scanf("%d",&a);            add(i,a,1);        }        spfa(1);         for(int i=1;i<=n;i++)printf("%d%c",dis[i],i==n?'\n':' ');    }    return 0;}
0 0
原创粉丝点击