1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include<iostream> #include<cstdio> #include<queue> #include<cstring> #define maxn 200010 #define maxm 300010 #define INF 1000000000 using namespace std;
int n, m;
int a[maxn];
const int N = 20; const int M = (1 << N) - 1;
struct Edge{ int to, next, w; }e[maxm + maxn + 20 * M]; int c1, head[maxn + M]; inline void add_edge(int u, int v, int w){ e[c1].to = v; e[c1].w = w; e[c1].next = head[u]; head[u] = c1++; }
int dis[maxn + M]; void mem(){ for(int i = 0; i < maxn + M; ++i) dis[i] = INF; }
deque<int> Q; bool vis[maxn + M]; void bfs(){ mem(); Q.push_back(1); dis[1] = 0; while(!Q.empty()){ int u = Q.front(); Q.pop_front(); if(vis[u]) continue; vis[u] = 1; for(int i = head[u]; ~i; i = e[i].next){ int v = e[i].to, w = e[i].w; if(dis[v] > dis[u] + w){ dis[v] = dis[u] + w; cout << v << " " << u << endl; if(w) Q.push_back(v); else Q.push_front(v); } } } }
int main(){ freopen("walk.in", "r", stdin); freopen("walk.out", "w", stdout); memset(head, -1, sizeof head); scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); for(int i = 1; i <= m; ++i){ int x, y; scanf("%d%d", &x, &y); add_edge(x, y, 1); } for(int i = 1; i <= n; ++i){ add_edge(i, n + a[i], 0), add_edge(n + a[i], i, 1); cout << i << " " << n + a[i] << endl; } for(int i = 1; i <= M; ++i) for(int j = 0; j < N; ++j) if(i >> j & 1){ if(!(i ^ 1 << j)) continue; add_edge(n + i, n + (i ^ 1 << j), 0); } bfs(); for(int i = 1; i <= n; ++i){ if(dis[i] == INF) puts("-1"); else printf("%d ", dis[i]); } return 0; }
|