1. 程式人生 > >【NOIp模擬賽】Walk

【NOIp模擬賽】Walk

using 出發 col input note out 無法 lar lin

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\n",dis[i+base]); fclose(stdin); fclose(stdout); return 0; }

【NOIp模擬賽】Walk