• [练习]: 并查集&最小生成树练习题 2017-06-06 18:47 45人阅读 评论(0) 收藏


    嗯。。都是些最最最基础的水题 直接模板就OK了。。 刚学的可以一做
    1.洛谷 并查集模板
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define N 10005
    #define M 200005
    using namespace std;
    int n,m,p;
    int fa[M];
    int findf(int x){
    	return fa[x]==x?x:fa[x]=findf(fa[x]);
    }
    void merge(int x,int y){
    	fa[findf(x)]=findf(y);
    }
    void solve(){
    	scanf("%d%d",&n,&m);
    	int k,x,y;
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&k,&x,&y);
    		if(k==1)
    		merge(x,y);
    		else {
    			if(findf(x)==findf(y))
    			printf("Y
    ");
    			else printf("N
    ");
    		}
    	}
    }
    int main(){
    	solve();
    	return 0;
    } 
    
    2.vijos1034家族
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define N 5005
    #define M 5005 
    using namespace std;
    int n,m,p;
    int fa[M];
    int findf(int x){
    	return fa[x]==x?x:fa[x]=findf(fa[x]);
    }
    void merge(int x,int y){
    	if(findf(x)!=findf(y)) 
    	fa[findf(x)]=findf(y);
    }
    void solve(){
    	scanf("%d%d%d",&n,&m,&p);
    	int x,y;
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&x,&y);
    		merge(x,y);
    	}
    	for(int i=1;i<=p;i++){
    		scanf("%d%d",&x,&y);
    		if(findf(x)==findf(y)) printf("Yes
    ");
    		else printf("No
    ");
    	}
    }
    int main(){
    	solve();
    	return 0;
    } 
    
    3.洛谷p1892团伙
    #include<cstdio>
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    int n,m;
    int flag;
    int f[2500];
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n*2;i++)
        f[i]=i; 
        for(int i=1;i<=m;i++) 
        {
            char t;int x,y;
            cin>>t>>x>>y;
            if(t=='F')      f[find(x)]=find(y);
            if(t=='E')
            {
                f[find(x+n)]=find(y); 
                f[find(y+n)]=find(x);
            }
        }
        int s=0;
        for(int i=1;i<=n;i++)
        if(f[i]==i) s++;
        printf("%d",s);
        return 0;
    } 
    
    4.洛谷p2078朋友
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 20005
    #define M 20005
    using namespace std;
    int n,m,p,q;
    int a[N],b[N];
    int findf1(int x) {
    	return a[x]==x?x:a[x]=findf1(a[x]);
    }
    int findf2(int x) {
    	return b[x]==x?x:b[x]=findf2(b[x]);
    }
    void merge1(int x,int y) {
    	if(findf1(x)<findf1(y)) swap(x,y);
    	a[findf1(x)]=findf1(y);
    }
    void merge2(int x,int y) {
    	if(findf2(x)<findf2(y)) swap(x,y);
    	b[findf2(x)]=findf2(y);
    }
    int main() {
    	scanf("%d%d%d%d",&n,&m,&p,&q);
    	int x,y;
    	for(int i=1; i<=n; i++) a[i]=i;
    	for(int i=1; i<=m; i++) b[i]=i;
    	for(int i=1; i<=p; i++) {
    		scanf("%d%d",&x,&y);
    		merge1(x,y);
    	}
    	for(int i=1; i<=q; i++) {
    		scanf("%d%d",&x,&y);
    		merge2(-x,-y);
    	}
    	int cnta=0,cntb=0;
    	for(int i=1; i<=n; i++) {
    		if(findf1(1)==findf1(i)) cnta++;
    	}
    	for(int i=1; i<=m; i++) {
    		if(findf2(1)==findf2(i)) cntb++;
    	}
    	printf("%d",min(cnta,cntb));
    	return 0;
    }
    5.洛谷p1547Out Of Hay
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #define N 2005
    #define M 10005 
    using namespace std;
    int n,m;
    int fa[N];
    struct node{
    	int l,r,w;
    }e[M];
    bool cmp(node x,node y){
    	return x.w<y.w;
    }
    int findf(int x){
    	return fa[x]==x?x:fa[x]=findf(fa[x]);
    }
    void merge(int x,int y){
    	fa[findf(x)]=findf(y);
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++)
    		scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);
    	sort(e+1,e+1+m,cmp);
    	int ans=0,tot=0;
    	for(int i=1;i<=m;i++){
    		int x=e[i].l;int y=e[i].r;
    		if(findf(x)!=findf(y))
    		{
    			merge(x,y);
    			ans=e[i].w;
    			tot++;
    		}
    		if(tot==n-1) break;
    	}
    	printf("%d",ans);
    	return 0;
    }
    6.洛谷p1536村村通
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 1005
    #define M 10005
    using namespace std;
    int n,m;
    int fa[N];
    int findf(int x){
    	return fa[x]==x?x:fa[x]=findf(fa[x]);
    }
    void merge(int x,int y){
    	fa[findf(x)]=findf(y);
    }
    int main(){
    	int tot=0;
    	while(1){
            bool flag=0;
    		tot=0;
    		scanf("%d",&n);
    		if(n==0) break;
    		scanf("%d",&m);
    		memset(fa,0,sizeof(fa));
    		for(int i=1;i<=n;i++)
    			fa[i]=i;
    		int x,y;
    		for(int i=1;i<=m;i++){
    			scanf("%d%d",&x,&y);
    			if(findf(x)!=findf(y)&&flag==0)
    			{
    				merge(x,y);
    				tot++;
    			}
    			if(tot==n-1)
                    flag=1;
    		}
    		printf("%d
    ",n-1-tot);
    	}
    	return 0;
    }
    
    7.洛谷p1396 营救(最小生成树+并查集)
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define N 10005
    #define M 20005
    using namespace std;
    int n,m,s,t;
    int fa[N];
    struct node{
    	int l,r,w;
    }e[M];
    void read(){
    	scanf("%d%d%d%d",&n,&m,&s,&t);
    	for(int i=1;i<=m;i++)
    		scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);
    }
    bool cmp(node xx,node yy){
    	return xx.w<yy.w;
    }
    int findf(int x){
    	return fa[x]==x?x:fa[x]=findf(fa[x]);
    }
    void merge(int x,int y){
    	fa[findf(x)]=findf(y);
    }
    int main(){
    	int ans=0,cnt=0;
    	read();
    	sort(e+1,e+1+m,cmp);
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++){
    		int x=e[i].l;
    		int y=e[i].r;
    		int w=e[i].w;
    		if(findf(x)!=findf(y)) {
    			cnt++;
    			merge(x,y);
    			ans=w;
    		}
    		if(findf(s)==findf(t)) break;
    		if(cnt==n-1) break;
    	}
    	printf("%d",ans);
    	return 0;
    }
    
    8.洛谷p1195口袋的天空
    /*
    P1195 口袋的天空
    n个点 m条边 连成k个树的最小代价  
    若k为1 则连成一棵MST 跑一次kruskal n-1次连边  
    若 k为2 为最后的图必须为 两颗MST n-2次连边
    同理 连成k个mst 进行 n-k次连边
    若进行者n-k次操作中 没有了边 (即cpp中的 i<m) 直接输出 No Answer
    */
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 1005
    #define M 10005
    using namespace std;
    int n,m,k;
    int fa[N];
    struct node{
    	int l,r,w;
    }e[M];
    int findf(int x){
    	return fa[x]==x?x:fa[x]=findf(fa[x]);
    }
    void merge(int x,int y){
    	fa[findf(x)]=findf(y);
    }
    void read(){
    	scanf("%d%d%d",&n,&m,&k);
    	int x,y,t;
    	for(int i=1;i<=m;i++)
    		scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);
    }
    bool cmp(node xx,node yy){
    	return xx.w<yy.w;
    }
    int main(){
    	read();
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	sort(e+1,e+1+m,cmp);
    	int tot=0,ans=0;
    	for(int i=1;i<=m;i++){
    		int x=e[i].l;
    		int y=e[i].r;
    		int w=e[i].w;
    		if(findf(x)!=findf(y)){
    			merge(x,y);
    			tot++;
    			ans+=w;
    		}
    		if(tot==n-k){
    			printf("%d",ans);
    			return 0;
    		}
    	}
    	printf("No Answer");
    	return 0;
    }
    
    9.洛谷P1111修复公路
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 1005
    #define M 100005
    using namespace std;
    int n,m;
    int fa[N];
    struct node{
    	int l,r,t;
    }e[M];
    int findf(int x){
    	return fa[x]==x?x:fa[x]=findf(fa[x]);
    }
    void merge(int x,int y){
    	fa[findf(x)]=findf(y);
    }
    void read(){
    	scanf("%d%d",&n,&m);
    	int x,y,t;
    	for(int i=1;i<=m;i++)
    		scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].t);
    }
    bool cmp(node xx,node yy){
    	return xx.t<yy.t;
    }
    int main(){
    	read();
    	sort(e+1,e+1+m,cmp);
    	int tot=0;
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++){
    		int x=e[i].l;
    		int y=e[i].r;
    		int t=e[i].t;
    		if(findf(x)!=findf(y)){
    			merge(x,y);
    			tot++;
    		}
    		if(tot==n-1){
    			printf("%d",t);
    			return 0;
    		}
    	}
    	printf("-1");
    	return 0;
    }
    


  • 相关阅读:
    【Redis过期Key监听】
    【ElasticSearch】ES线上脏数据处理
    【MySQL】实现线上千万数据表添加字段操作以及缓存刷新
    【转】【堆外内存】堆内内存与堆外内存
    【Redis连接超时】记录线上RedisConnectionFailureException异常排查过程
    【ElasticSearch】ES 读数据,写数据与搜索数据的过程
    【ElasticSearch】shards,replica,index之间的关系
    tomorrow多线程启动
    request接口下载附件
    request接口上传附件
  • 原文地址:https://www.cnblogs.com/xljxlj/p/7183623.html
Copyright © 2020-2023  润新知