本文主要是介绍PREV-54 试题 历届试题 合根植物,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接 PREV-54 试题 历届试题 合根植物
题目描述
资源限制
时间限制:2.0s 内存限制:256.0MB
问题描述
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入格式
第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。
接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)
接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。
格子的编号一行一行,从上到下,从左到右编号。
比如:5 * 4 的小格子,编号:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
样例输入
5 4
16
2 3
1 5
5 9
4 8
7 8
9 10
10 11
11 12
10 14
12 16
14 18
17 18
15 19
19 20
9 13
13 17
样例输出
5
解题思路
并查集模板,稍做一点修改。
程序代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,kk,x,y;
int fa[1000005],ans;
inline int read() {int x=0,w=1;char ch=0;while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();if(ch=='-') w=-1,ch=getchar();while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();return x*w;
}
inline int cmp(int a,int b) {return a<b;}
int gf(int x) {return x==fa[x]?x:fa[x]=gf(fa[x]);}
//找爸爸
inline void union1(int a,int b) {int f1=gf(a),f2=gf(b);if(f1!=f2){fa[f1]=f2;}
}//并查集
int main() {cin>>m>>n;cin>>kk;for(int i=1;i<=n*m;++i) fa[i]=i;for(int i=1;i<=kk;++i) {//把有关联的和根植物放在一个集合内cin>>x>>y;union1(y,x);}for(int i=1;i<=n*m;++i) {int xx=gf(i);}//在向上寻找根源,并且都将自己的父亲更新为祖父ans=1;sort(1+fa,1+fa+n*m,cmp);//排序for(int i=2;i<=n*m;++i)if(fa[i]!=fa[i-1]) ans++;//比较不同的祖父有多少个cout<<ans<<endl;return 0;
}
疑问
我把那个递归版的找爸爸改为非递归版之后就不行了,不知道为何,非递归版找爸爸好像也没问题。以下是非递归版程序。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,kk,x,y;
int fa[1000005],ans;
inline int read() {int x=0,w=1;char ch=0;while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();if(ch=='-') w=-1,ch=getchar();while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();return x*w;
}
inline int cmp(int a,int b) {return a<b;}
//int gf(int x) {return x==fa[x]?x:fa[x]=gf(fa[x]);}
inline int gf(int x) {//非递归版找爸爸int u=x,v=x;while(u!=fa[u]) u=fa[u];while(v!=fa[v]) {v=fa[v];fa[v]=u; }return u;
} /*inline int gf(int x){int p=x;while(p!=fa[p])p=fa[p];while(x!=fa[x]){x=fa[x];fa[x]=p;}return p;
}*/
inline void union1(int a,int b) {int f1=gf(a),f2=gf(b);if(f1!=f2){fa[f1]=f2;}
}
int main() {cin>>m>>n;cin>>kk;for(int i=1;i<=n*m;++i) fa[i]=i;for(int i=1;i<=kk;++i) {cin>>x>>y;union1(y,x);}for(int i=1;i<=n*m;++i) {int xx=gf(i);}ans=1;sort(1+fa,1+fa+n*m,cmp);for(int i=2;i<=n*m;++i)if(fa[i]!=fa[i-1]) ans++;cout<<ans<<endl;return 0;
}
这篇关于PREV-54 试题 历届试题 合根植物的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!