Problem C: 单向迷宫
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 94 Solved: 2
[ Submit][ Status][ Web Board]
Description
ZJUT有一个单向迷宫,里面所有的道路都是单向的,对于一个固定的节点,能在下一步走到的节点是固定的,Rakkit已经获取了这个迷宫每个节点能直接走到的点是哪个,现在需要你做一些统计。对于每个询问x,y,求出x节点在走y步之后达到的点
Input
对于每组数据
第一行,一个n表示迷宫的节点数
接下来n个数表示每个节点直接可以走到的点
接下来一行一个字母q表示询问的个数
接下来q行每行给出两个字母x,y,表示一个询问
【数据范围】
1<=x<=n<=100000
1<=q<=100000
10<=y<=1000000000
Output
对于每一个询问,给出一个答案,一个答案占一行
Sample Input
3
2 3 1
3
1 1
1 2
2 3
Sample Output
2
3
2
这必须要简化,要省去不必要的向后遍历。然后就写了我2个小时,才终于订正过来
#include<iostream>
#include<algorithm>
#include <stdio.h>
#include<stdlib.h>
#include<string>
using namespace std;
#define M 100010
int head[M],nextt[M],flag[M],dis[M],loop[M],diss[M],front[M],jiechu[M],up[M],flagg[M];
int *circle[M];
int main()
{
int i,j,n,k,p,num,now_head,q,x,y,jc;
unsigned int bs;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
head[i]=-1;
flag[i]=0;
flagg[i]=0;
nextt[i]=-1;
up[i]=-1;
dis[i]=-1;
loop[i]=-1;
}
for(i=1;i<=n;i++)
{
scanf("%d",&p);
nextt[i]=p;
up[p]=i;
}
k=0;
for(i=1;i<=n;i++)
{
if(flag[i]==0)
{
flagg[i]=1;
p=i;
while(1)
{
flagg[p]=1;
if(up[p]==-1||flagg[up[p]]==1)
break;
p=up[p];
}
}
else continue;
num=0;
now_head=k;
dis[p]=num;
diss[num]=p;
flag[p]=1;
flagg[p]=1;
head[p]=k;
p=nextt[p];
while(1)
{
num++;
if(flag[p]==1)
{
if(head[p]==k)
{
loop[k]=num-dis[p];
front[k]=dis[p];
jiechu[k]=p;
// printf("front[%d]=%d,jiechu[%d]=%d\n",k,front[k],k,jiechu[k]);
}
else
{
jiechu[k]=p;
front[k]=num;
//printf("front[%d]=%d,jiechu[%d]=%d\n",k,front[k],k,jiechu[k]);
}
break;
}
dis[p]=num;
diss[num]=p;
head[p]=k;
flag[p]=1;
flagg[p]=1;
p=nextt[p];
}
circle[k]=new int[num];
for(j=0;j<num;j++)
{
*(circle[k]+j)=diss[j];
}
k++;
}
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&x,&y);
// cout<<"y="<<y<<endl;
now_head=head[x];
bs=y+dis[x];
//printf("front=%d,jiechu=%d\n",front[now_head],jiechu[now_head]);
if(bs<front[now_head])
{
printf("%d\n",*(circle[now_head]+bs));
}
else
{
while(1)
{
bs-=front[now_head];
jc=jiechu[now_head];
now_head=head[jc];
bs+=dis[jc];
//printf("new,now_head=%d\n",now_head);
if(bs<front[now_head])
{
printf("%d\n",*(circle[now_head]+bs));
break;
}
else
{
if(loop[now_head]==-1)
continue;
bs-=front[now_head];
bs=bs%loop[now_head];
bs+=front[now_head];
printf("%d\n",*(circle[now_head]+bs));
break;
}
}
}
}
}
}