列表

详情


NC213810. LotsofEdges

描述

有 n 个点,每个点有点权 。若 (指二进制下按位与),则在 i,j 间连一条边权为 1 的边。
求 S 到 的最短路。

输入描述

第一行两个正整数 n,S。
接下来一行 n 个非负整数,第 i 个为 a_i
对于所有数据,

输出描述

一行 n 个整数,第 i 个为 S 到 i 的最短路长度。不能到达输出 -1。

示例1

输入:

5 3
2 3 4 5 6

输出:

1 1 0 2 -1

说明:

样例解释:连了 (1,3),(2,3),(1,4) 三条边。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 377ms, 内存消耗: 2580K, 提交时间: 2021-01-13 16:01:34

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+200,M=17;
int a[N],n,s,d[1<<M];
bool vis[1<<M];
int main()
{
    scanf("%d%d",&n,&s);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),vis[a[i]]=1;
    int B=(1<<17)-1;
    memset(d,-1,sizeof d);
	d[a[s]]=0;
	queue<int>q;
	q.push(a[s]);
	while(!q.empty())
	{
	    int u=q.front();q.pop();
		int v=B^u;
		for(int w=v;w;w=(w-1)&v)
	    {
		    if(vis[w]&&d[w]==-1){
		    	d[w]=d[u]+1;q.push(w);
			}
		}	
		if(vis[0]&&d[0]==-1){
			d[0]=d[u]+1;q.push(0);
		}
	}  
	for(int i=1;i<=n;i++)
	{
		if(d[a[i]])printf("%d ",d[a[i]]);
		else if(i==s)printf("0 ");
		else if(a[i]==0)printf("1 ");
		else printf("2 ");
	}  
} 

上一题