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\n",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\n");
            else printf("%d\n",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\n",ans);
    return 0;
}
poj1182

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

posted @ 2018-08-03 20:38  AKCqhzdy  阅读(153)  评论(0编辑  收藏  举报