列表

详情


NC15432. 无向图中的最短距离

描述

有一个n个点的无向图,有m次查询,每次查询给出一些(xi,yi)

dist(x,y)表示xy点在图中最短距离,dist(x,x)=0,如果x,y不连通则dist(x,y) = inf

每次查询图中有多少个点v与至少一个这次询问给出的(xi,yi)满足dist(v,xi)<=yi

输入描述

第一行三个数表示n,m,q

之后m行每行两个数x,y表示有一条x与y之间的边,边权为1

之后q次询问,每个询问先给你一个数a

之后一行2a个数,第2i-1个数xi和第2i个数yi表示一个二元组(xi,yi

输出描述

输出q行,每行一个数表示这次询问的答案

示例1

输入:

5 6 6
2 3 
1 3 
2 5 
1 3 
3 2 
2 5
1
3 1
1
1 1
1
1 4
1
5 2
1
1 4
2
1 0 5 1

输出:

3
2
4
3
4
3

原站题解

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

C++(g++ 7.5.0) 解法, 执行用时: 335ms, 内存消耗: 126136K, 提交时间: 2022-08-03 20:08:00

#include<cstdio>
#include<bitset>
int read()
{
	int a=0;char c;
	while((c=getchar())<'0');
	while(c>='0')a=a*10+(c^48),c=getchar();
	return a;
}
int n,m;std::bitset<1000>r[1000][1000],e[1000];
void bfs(int s)
{
	r[s][0].set(s);
	std::bitset<1000>now,next=e[s];now.set(s),next.set(s);
	for(int i=1;i<n;i++)
	{
		auto t=now^next;r[s][i]=now=next;
		for(int v=t._Find_first();v<n;v=t._Find_next(v))next|=e[v];
		if(r[s][i]==r[s][i-1])for(i++;i<n;i++)r[s][i]=r[s][i-1];
	}
}
int main()
{
	n=read(),m=read();int q=read(),u,v,a;
	while(m--)u=read()-1,v=read()-1,e[u].set(v),e[v].set(u);
	for(int i=0;i<n;i++)bfs(i);
	while(q--)
	{
		std::bitset<1000>ans;a=read();
		while(a--)u=read()-1,v=read(),ans|=r[u][std::min(n-1,v)];
		printf("%d\n",ans.count());
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 1027ms, 内存消耗: 128680K, 提交时间: 2020-05-05 13:47:20

#include<bits/stdc++.h>
using namespace std;

struct node
{
	int x,h;
}Q[1005];
int i,j,a,n,m,q;
bitset<1005>T[1005][1005];
vector<int>R[1005];
void BFS(int sx)
{
	int i,j,x,h,r=1,f=0;
	bool V[1005]={0};
	Q[0].x=sx,Q[0].h=0,V[sx]=1;
	while(r!=f)
	{
		x=Q[f].x,h=Q[f++].h;
		T[sx][h][x]=1;
		for(i=0;i<R[x].size();i++)
		{
			j=R[x][i];
			if(!V[j])V[j]=1,Q[r].x=j,Q[r++].h=h+1;
		}
	}
	for(i=1;i<=n-1;i++)T[sx][i]|=T[sx][i-1];
}
int main()
{
	scanf("%d%d%d",&n,&m,&q);
	while(m--)
	{
		scanf("%d%d",&i,&j);
		R[i].push_back(j),R[j].push_back(i);
	}
	for(i=1;i<=n;i++)BFS(i);
	while(q--)
	{
		scanf("%d",&a);
		bitset<1005>ans;
		while(a--)
		{
			scanf("%d%d",&i,&j),j=min(j,n-1);
			ans|=T[i][j];
		}
		printf("%d\n",ans.count());
	}
	return 0;
}

上一题