Fork me on GitHub

P2024 食物链(two)

xy画的图luogu

vijos

两种方法

一、带权并查集:问题 front做差

#include<iostream>
#include<cstdio> 
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
int f[50001],front[500001],n,k,ans=0;
int find(int x)
{
    if(f[x]==x) return x;
    int fx=find(f[x]);
    front[x]=(front[x]+front[f[x]])%3;
    return f[x]=fx;
}
int main()
{
    scanf("%d%d",&n,&k);

    for(int i=1;i<=n;i++) 
      f[i]=i;

    for(int i=1;i<=k;i++)
    {
        int p,x,y;
        scanf("%d%d%d",&p,&x,&y);
        if(x>n||y>n||(x==y&&p==2)||x<1||y<1) 
        {
            ans++;
            continue;
        }

        int fx=find(x),fy=find(y);

        if(fx!=fy)
        {
            f[fx]=fy;//决定front[x]-front[y](should)==p-1!!!
            front[fx]=(front[y]+p-1-front[x]+3)%3;
        }
        else
        {
            if(p==1) 
            {
                if(front[x]!=front[y]) 
                    ans++;
            }
            if(p==2)
            {
                if((front[y]+1)%3!=front[x])
                    ans++; 
            }
            /*if((front[y]+p-1+3)%3!=front[x])//front[x]-front[y](should)==p-1!!!
            ans++;*/
        }
    }
    printf("%d",ans);
    return 0;
}

反集:问题 判断范围
三倍数组
n+1~2*n 给吃它的,2* n+1~3*n吃它的

#include<iostream>
#include<cstdio> 
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
int f[50001*3],n,k,ans=0;
int find(int x)
{
    if(f[x]==x) return x;
    return f[x]=find(f[x]);
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n*3;i++) 
      f[i]=i;

    for(int i=1;i<=k;i++)
    {
        int p,x,y;
        scanf("%d%d%d",&p,&x,&y);
        int fx=find(x),fx2=find(x+n),fx3=find(x+2*n);//fx2是x吃的,fx3是吃x的
        int fy=find(y),fy2=find(y+n),fy3=find(y+2*n);
        if(x>n||y>n||(x==y&&p==2)||x<1||y<1) //是否超范围?ans++
        {
            ans++;
            continue;
        }

        if(p==1)
        {
            //if(fx==fy) continue;
            if(fx!=fy)
            {
                if(fx2==fy||fx3==fy||fx==fy2||fx==fy3||fx2==fy3||fx3==fy2)
                   ans++;
                else f[fy]=fx,f[fy2]=fx2,f[fy3]=fx3;

                continue;
            }
        }
        if(p==2)
        {
            if(fx==fy||fx2==fy2||fx3==fy3||fx3==fy||fy3==fx2)
               ans++;
            else f[fx2]=fy,f[fy3]=fx,f[fy2]=fx3;

            continue;
        }
    }

    printf("%d",ans);
    return 0;
}
posted @ 2017-02-26 11:26  primes  阅读(323)  评论(0编辑  收藏  举报