• 0x41 并查集


    太菜了才做到并查集啊啊啊啊啊啊啊啊啊啊啊

    还是很有收获的说

    bzoj4195: [Noi2015]程序自动分析

    好题 poj1456 感受到并查集传递性的美妙啊!对于一个商品,去找他过期前那天的集合假如大于0相当于可以在这天卖出,然后这个集合和前一个集合合并!

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node{int v,d;}a[11000];
    bool cmp(node n1,node n2){return n1.v>n2.v;}
    
    int fa[11000];
    int findfa(int x)
    {
        if(fa[x]==x)return x;
        fa[x]=findfa(fa[x]);return fa[x];
    }
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1;i<=n;i++)
                scanf("%d%d",&a[i].v,&a[i].d);
            sort(a+1,a+n+1,cmp);
            
            for(int i=1;i<=10000;i++)fa[i]=i;
            
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                if(findfa(a[i].d)!=0)
                {
                    ans+=a[i].v;
                    int fx=findfa(a[i].d);
                    int fy=findfa(fx-1);
                    fa[fx]=fy;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    poj1456

    NOI2002银河英雄传说 这个我没有系统的学“拓展域”和“边带权”,导致写的很挫。。用了奇技淫巧。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    char ss[5];
    int fa[31000],d[31000];
    int findfa(int x)
    {
        if(fa[x]<0)return x;
        
        int dis=d[x];
        int f=findfa(fa[x]);
        
        d[x]=dis+d[fa[x]];fa[x]=f;
        return fa[x];
        
    }
    int main()
    {
        for(int i=1;i<=30000;i++)fa[i]=-i,d[i]=0;
        
        int Q,x,y;
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%s%d%d",ss+1,&x,&y);
            if(ss[1]=='M')
            {
                int fx=findfa(x),fy=findfa(y);
                int t=fa[fy];
                fa[fy]=-fa[fx], d[fy]=1;
                fa[fx]=t;
            }
            else
            {
                int fx=findfa(x),fy=findfa(y);
                if(fx!=fy)printf("-1
    ");
                else printf("%d
    ",max(d[x],d[y])-min(d[x],d[y])-1);
            }
        }
        return 0;
    }
    NOI2002银河英雄传说

    正经的边带权,还是很秀的边带权

    poj1733 Parity game

    poj1182 食物链这题之前搞死人,正经的拓展域~

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int fa[310000];
    int findfa(int x)
    {
        if(x==fa[x])return x;
        fa[x]=findfa(fa[x]);return fa[x];
    }
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n*3;i++)fa[i]=i;
        
        int d,x,y,ans=0;
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d%d",&d,&x,&y);
            if(x>n||y>n){ans++;continue;}
            
            int fx1=findfa(x),fy1=findfa(y);
            int fx2=findfa(x+n),fy2=findfa(y+n);
            int fx3=findfa(x+n*2),fy3=findfa(y+n*2);
            if(d==1)
            {
                if(fx1==fy2||fy1==fx2)ans++;
                else fa[fx1]=fy1, fa[fx2]=fy2, fa[fx3]=fy3;
            }
            else
            {
                if(fx1==fy1||fx1==fy2)ans++;
                else fa[fy1]=fx2, fa[fy2]=fx3, fa[fy3]=fx1;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    poj1182

    感觉这个博客就是让我存代码的

  • 相关阅读:
    mysql之创建数据库,创建数据表
    mysql之group by,order by
    一个人选出2门以上不及格的课程sql语句
    GIt入门
    数据库索引工作原理
    题目:50个人围城一圈数到3和3的倍数时出圈,问剩下的人是谁?原来的位置是多少?
    约瑟夫环:递归算法
    K-means算法的java实现,聚类分析681个三国武将
    java用一个for循环输出99乘法表
    写一个基于UDP协议的聊天小程序
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9416188.html
Copyright © 2020-2023  润新知