Interesting Computer Game(DFS||并查集)

Interesting Computer Game(DFS||并查集)

思路:转化为连通子图 G < V , E > G<V,E> 的顶点数之和,若无环贡献为顶点数,否则为顶点数减1.

d f s dfs 做法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
PII p[N];
int a[N<<1],es,ps,vis[N<<1],ans;
vector<int>e[N];
void dfs(int u,int fa){
	es+=e[u].size(),ps++,vis[u]=1;
	for(int v:e[u])
		if(!vis[v]&&v!=fa) dfs(v,u);
}
void fun(int x){
	es=ps=0;
	dfs(x,0);es>>=1;
	ans+=es>=ps?ps:ps-1;
}
int main(){
	int t;
	scanf("%d",&t);
	for(int k=1;k<=t;k++){
		int n,tot=ans=0;
		scanf("%d",&n); 
		for(int i=1;i<=n;i++){
			scanf("%d%d",&p[i].fi,&p[i].se);
			a[++tot]=p[i].fi,a[++tot]=p[i].se;
		}
		sort(a+1,a+tot+1);tot=unique(a+1,a+tot+1)-a-1;
		for(int i=1;i<=tot;i++) e[i].clear(),vis[i]=0;
		for(int i=1;i<=n;i++){
			int x=p[i].fi,y=p[i].se;
			x=lower_bound(a+1,a+tot+1,x)-a;
			y=lower_bound(a+1,a+tot+1,y)-a;
			e[x].pb(y),e[y].pb(x);
		}
		for(int i=1;i<=tot;i++)
			if(!vis[i]) fun(i);
		printf("Case #%d: %d\n",k,ans);
	} 
	return 0;
}

并查集做法:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
PII p[N];
int a[N<<1],es,ps,vis[N<<1],ans,s[N<<1],c[N<<1];
int find(int x){return x==s[x]?x:s[x]=find(s[x]);}
int main(){
	int t;
	scanf("%d",&t);
	for(int k=1;k<=t;k++){
		int n,tot=0;
		scanf("%d",&n); 
		for(int i=1;i<=n;i++){
			scanf("%d%d",&p[i].fi,&p[i].se);
			a[++tot]=p[i].fi,a[++tot]=p[i].se;
		}
		sort(a+1,a+tot+1);tot=unique(a+1,a+tot+1)-a-1;
		for(int i=1;i<=tot;i++) s[i]=i,c[i]=0;
		for(int i=1;i<=n;i++){
			int x=p[i].fi,y=p[i].se;
			x=lower_bound(a+1,a+tot+1,x)-a;
			y=lower_bound(a+1,a+tot+1,y)-a;
			x=find(x),y=find(y);
			if(x!=y) s[x]=y,c[y]|=c[x];
			else c[x]=1;
		}
		ans=tot;
		for(int i=1;i<=tot;i++)
			if(find(i)==i&&!c[i]) ans--;
		printf("Case #%d: %d\n",k,ans);
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107771877