zoukankan      html  css  js  c++  java
  • 20200116

    并查集

    题目描述

    现在有一个并查集,你需要完成合并和查询操作。

    输入格式

    第一行包含两个整数NN、MM,表示共有NN个元素和MM个操作。
    接下来MM行,每行包含三个整数ZiZi、XiXi、YiYi
    Zi=1Zi=1时,将XiXi与YiYi所在的集合合并
    Zi=2Zi=2时,输出XiXi与YiYi是否在同一集合内,是的话输出YY;否则话输出NN

    输出格式

    如上,对于每一个Zi=2Zi=2的操作,都有一行输出,每行包含一个大写字母,为YY或者NN

    输入输出样例

    输入

    4 7
    2 1 2
    1 1 2
    2 1 2
    1 3 4
    2 1 4
    1 2 3
    2 1 4

    输出

    N
    Y
    N
    Y

    数据规模

    对于30%30%的数据,N10N≤10,M20M≤20;
    对于70%70%的数据,N100N≤100,M1000M≤1000;
    对于100%100%的数据,N10000N≤10000,M200000M≤200000。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define N 50005
    using namespace std;
    //get together jihe
    int fa[N];
    int n; 
    void init(){
        for(int i=1;i<=n;i++) fa[i]=i;
    }
    int find(int x){
        return x==fa[x]?x:fa[x]=find(fa[x]);
    }
    void uni(int x,int y){
        fa[find(x)]=find(y);
    }
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) fa[i]=i;
    //init();
        while(m--){
            int a=0,b=0,c=0;
            scanf("%d%d%d",&a,&b,&c);
            if(a==1){
                fa[find(b)]=find(c);
            }
            else if(a==2){
                if(find(b)==find(c)){
                    printf("Y
    ");
                }
                else{
                    printf("N
    ");
                }
            }
        }
        return 0;
    }

    图论

    链式前向星与vector

    基本实现

    #include <cstdio>
    struct node{
        int to,next,val;
    }edge[N];
    void add(int x,int y,int val1){
        e[cnt]=(node){y,head[x],val1};
        head[x]=cnt++;
    }
    memset(head,-1,sizeof(head));
    cnt=0;
    for(int i=head[x];i!=-1;i=edge[i].next){
        int to1=edge[i].to;
        //do something
    }

    My code

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define N 5005
    #define M 20005
    using namespace std;
    int cnt=0,head[N]; 
    struct node{
        int to,next,val;
    }edge[N];
    void add(int x,int y,int val1){
        edge[++cnt].next=head[x];
        edge[cnt].to=y;
        edge[cnt].val=val1;
        head[x]=cnt;
        
    }
    int main(){
        
    }
    memset(head,-1,sizeof(head));
    for(int i=head[x];i!=-1;i=edge[i].next){
        int to1=edge[i].to;
        //do something
    }

    最小生成树

    我觉得他很重要!!!!!!!!

    Kruskal (并查集+链式前向星)

    //Kraskul
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define N 5005
    #define M 200005
    using namespace std;
    int cnt=0,head[M],fa[M];//fa维护点的连通性 
    struct node{
        int to,next,val;
    }edge[M];
    int find(int x){
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    bool cmp(node x,node y){
        return x.val<y.val;
    }
    void add(int x,int y,int val1){
        edge[++cnt].next=head[x];
        edge[cnt].to=y;
        edge[cnt].val=val1;
        head[x]=cnt;
    }
    int tgn,tgto,ans;
    int main(){
        memset(head,-1,sizeof(head));
        int n,m;
        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",&edge[i].next,&edge[i].to,&edge[i].val);
        }
        //kruskal
        sort(edge+1,edge+m+1,cmp);
        for(int i=1;i<=m;i++){
            tgn=find(edge[i].next);
            tgto=find(edge[i].to);
            if(tgn==tgto){
                continue;
            }
            //若已经联通,则不需要这一条边
            ans+=edge[i].val;
             //边权记录答案
            fa[tgto]=tgn; //联通tgto和tgn 
            if(++cnt==n-1){
                break;
            }
            //边为点数减一时停止 
        }
        if(ans!=0) printf("%d",ans);
        else printf("orz");
        return 0;
    }
    /* 
    for(int i=head[x];i!=-1;i=edge[i].next){
        int to1=edge[i].to;
        //do something
    }
    */
  • 相关阅读:
    寒假学习记录19
    寒假学习记录18
    寒假学习记录17
    寒假学习记录16
    寒假学习记录15
    寒假学习记录14
    寒假学习记录13
    寒假学习记录12
    寒假学习记录11
    学习进度(10)
  • 原文地址:https://www.cnblogs.com/ziyuan122625/p/12213625.html
Copyright © 2011-2022 走看看