传送门:How Many Tables
- 模板代入
- 判断几个连通分支
- DFS亦可完成
【并查集】
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 50005; int n,m; int a,b,ans; int pre[maxn]; void init() { for(int i=1;i<=n;i++) pre[i] = i; } int findPre(int x) { if(pre[x] == x) return x; return findPre(pre[x]); //并没有路径压缩 } void unite(int x,int y) { int rx = findPre(x); int ry = findPre(y); if(rx==ry) return; else pre[ry] = rx; //不是pre[y] = x; } int main() { int flag=0,T; cin>>T; while(T--){ cin>>n>>m; init(); ans = 0; for(int i=1;i<=m;i++){ cin>>a>>b; unite(a,b); } //判断连通分量的数量 for(int i=1;i<=n;i++){ if(i==pre[i]){ ans++; } } cout<<ans<<endl; } return 0; }
【DFS】
#include<cstdio> #include<iostream> #include<cstring> using namespace std; bool vis[1005],lj[1005][1005]; int n,m; void dfs(int start) { vis[start]=false; for(int i=1;i<=n;i++) { if(vis[i]&&lj[start][i]) { vis[i]=false; dfs(i); } } } int main() { int t; scanf("%d",&t); while(t--) { int a,b,cnt=0; memset(vis,true,sizeof(vis)); memset(lj,false,sizeof(lj)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); lj[a][b]=lj[b][a]=true; } for(int j=1;j<=n;j++) { if(vis[j]) { //printf("%d ",j); cnt++; dfs(j); } } printf("%d ",cnt); } return 0; }