Input file: walk.in
Output file: walk.out
Time limit: 1 seconds
Memory limit: 128 megabytes
在比特镇一共有 n 个街区,编号依次为 1 到 n,它们之间通过若干条单向道路连接。
比特镇的交通系统极具特色,除了 m 条单向道路之外,每个街区还有一个编码 vali,不同街区可能
拥有相同的编码。如果 vali and valj = valj,即 vali 在二进制下与 valj 做与运算等于 valj,那么也会
存在一条额外的从 i 出发到 j 的单向道路。
Byteasar 现在位于 1 号街区,他想知道通过这些道路到达每一个街区最少需要多少时间。因为比特
镇的交通十分发达,你可以认为通过每条道路都只需要 1 单位时间。
Input
第一行包含两个正整数 n; m,表示街区的总数以及道路的总数。
第二行包含 n 个正整数 val1; val2; :::; valn,分别表示每个街区的编码。
接下来 m 行,每行包含两个正整数 ui; vi,表示一条单向道路,起点为 ui,终点为 vi。
Output
输出 n 行,每行一个整数,其中第 i 行输出到达第 i 个街区的最少时间,如果无法到达则输出 -1。
Examples
walk.in | walk.out |
5 2 5 4 2 3 7 1 4 2 3 |
0 1 2 1 -1 |
Page 6 of 7
Claris’ Contest # 2
Day 1
Notes
对于 100% 的数据, 1 ≤ ui; vi ≤ n; 1 ≤ vali < 220。
测试点编号 | n | m | vali |
1 | = 5 | ≤ 10 | < 24 |
2 | = 5 | ≤ 10 | < 24 |
3 | = 2000 | ≤ 5000 | < 210 |
4 | = 2000 | ≤ 5000 | < 210 |
5 | = 200000 | ≤ 300000 | < 215 |
6 | = 200000 | ≤ 300000 | < 215 |
7 | = 200000 | ≤ 300000 | < 215 |
8 | = 200000 | ≤ 300000 | < 220 |
9 | = 200000 | ≤ 300000 | < 220 |
10 | = 200000 | ≤ 300000 | < 220 |
分析
代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn=3000000; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m,num,base=1<<20; int hd0[maxn],hd1[maxn],dis[maxn]; queue<int>q; struct node { int next,to; }e[800000]; inline void add0(int from,int to) { e[++num].next=hd0[from]; e[num].to=to; hd0[from]=num; } inline void add1(int from,int to) { e[++num].next=hd1[from]; e[num].to=to; hd1[from]=num; } void dfs(int x,int len) { if(dis[x]>=0) return; if(x>base) q.push(x); dis[x]=len; for(int i=hd0[x];i;i=e[i].next) dfs(e[i].to,len); if(x>=base) return; for(int i=0;i<20;i++) if(x&(1<<i)) dfs(x^(1<<i),len); } int main() { freopen("walk.in","r",stdin); freopen("walk.out","w",stdout); n=read();m=read(); for(int i=1;i<=n;i++) { int x=read(); add0(x,i+base); add1(i+base,x); } for(int i=1;i<=m;i++) { int x,y; x=read(); y=read(); add1(x+base,y+base); } memset(dis,-1,sizeof(dis)); q.push(base+1); dis[base+1]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=hd1[u];i;i=e[i].next) dfs(e[i].to,dis[u]+1); } for(int i=1;i<=n;i++) printf("%d ",dis[i+base]); fclose(stdin); fclose(stdout); return 0; }