列表

详情


NC200046. Immortal Grass

描述

为了登上神秘之山,Vanis开启了他的上山之旅。

现在他站在某个古怪而低矮的建筑物旁,据说山中总共有n个这样的建筑物,每个建筑物上都刻着互不相同的介于1到n之间(包含1和n)的整数编号,他面前的这个建筑物上写着数字k。
山间道路崎岖,有时还会有奇奇怪怪的某种草本植物挡路,村民把这种植物叫做“不朽之草”,或简称为“仙草 (immortal grass)”。受到热心村民的指点,Vanis知道了哪些建筑之间有道路能够互相到达,这样的线索总共有m条。
Vanis想知道从它所在的编号为k的建筑物出发,最多能到达多少个不同编号的建筑(包括最初的建筑物k)。

形式化地说,有一个包含n个顶点m条边的无向图,从k号顶点开始走,希望知道最多能到达多少个包含k在内的不同的顶点。边和顶点都可途径多次。

输入描述

第一行输入三个整数n,m,k,分别表示建筑的数量,道路的数量,以及Vanis面前的建筑物的编号,相邻整数间使用一个空格符分隔。
接下来输入m行,每行包含两个正整数,之间使用一个空格符分隔,将这种输入开始的第i行的两个整数记作u_iv_i,表示u_iv_i之间有一条无向边。

数据规范:
* .
* .
* .
* .
* .
* 保证无重边和自环。
* 保证所有输入都是整数。

输出描述

输出一个正整数,表示能够到达的顶点个数。

示例1

输入:

5 3 3
1 3
2 5
2 4

输出:

2

原站题解

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

C++14(g++5.4) 解法, 执行用时: 35ms, 内存消耗: 2020K, 提交时间: 2019-12-07 13:14:52

#include<bits/stdc++.h>
using namespace std;
int fa[100010],sz[100010],n,m,k;
int ask(int x){
    return x==fa[x]?x:fa[x]=ask(fa[x]);
}

int main(){
    scanf("%d%d%d",&n,&m,&k);
    for (int i=1;i<=n;++i) fa[i]=i,sz[i]=1;
    for (int i=1,x,y;i<=m;++i){
        scanf("%d%d",&x,&y);
        int lx=ask(x),ly=ask(y);
        if (lx==ly) continue;
        sz[lx]+=sz[ly];
        fa[ly]=lx;
    }
    printf("%d\n",sz[ask(k)]);
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 34ms, 内存消耗: 1508K, 提交时间: 2019-12-07 12:35:27

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int n,m,k,fa[MAXN];

int findfa(int x) {return x==fa[x]?x:fa[x]=findfa(fa[x]);}

int main(){
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		fa[findfa(u)]=fa[findfa(v)];
	}
	int ans=0;
	for(int i=1;i<=n;i++)
		if(findfa(i)==findfa(k))
			ans++;
	printf("%d\n",ans);
	return 0;
}

上一题