【codevs 1074】食物链

来源:互联网 发布:餐厅门店经营数据 编辑:程序博客网 时间:2024/04/30 15:40

加权并查集
感谢Loi_lxt博客的详细解释。Orz

#include<cstdio>#include<iostream>#include<cstring>using namespace std;struct alice{    int f,v;}fa[50005];int n,k,cnt=0;alice find(int x){    if(fa[x].f==x) return fa[x];    int f=fa[x].f;    fa[x].f=find(fa[x].f).f;    fa[x].v=(fa[x].v+fa[f].v+3)%3;    return fa[x];}void merge(int x,int y,int c){    int fx=find(x).f,fy=find(y).f;    fa[fx].f=fy;    fa[fx].v=(c+fa[y].v-fa[x].v+3)%3;}bool pd(int b,int x,int y){    if(x>n||y>n) return false;    if(b==2&&x==y) return false;    return true;}int main(){    scanf("%d%d",&n,&k);    for(int i=1;i<=n;i++)    {        fa[i].f=i;        fa[i].v=0;    }    int a,x,y;    for(int i=1;i<=k;i++)    {        scanf("%d%d%d",&a,&x,&y);        if(pd(a,x,y))        {            if(find(x).f!=find(y).f) merge(x,y,a-1);            else if((fa[x].v-fa[y].v+3)%3!=(a-1+3)%3) cnt++;        }        else cnt++;    }    printf("%d\n",cnt);    return 0;}

扩展域并查集。开三倍空间,x1(或y1)代表自己的种群,x2(或y2)代表食物的种群,x3(或y3)代表敌人的种群。
PS:调了半天,原来是并查集打错了(哭)。

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int n,m,cnt=0;const int maxn=3*50000+5;int fa[maxn],rank[maxn];int find(int x){    return fa[x]==x?x:fa[x]=find(fa[x]);}void merge(int x,int y){    x=find(x),y=find(y);    if(x==y) return;    if(rank[x]<rank[y])        fa[x]=y;    else     {        fa[y]=x;        if(rank[x]==rank[y]) rank[x]++;    }    return;}bool tp(int a,int x,int y){    if(x>n||y>n) return 0;    if(a==2)    {        if(x==y) return 0;    }    return 1;}int main(){    memset(rank,0,sizeof(rank));    scanf("%d%d",&n,&m);    for(int i=1;i<=n*3;i++) fa[i]=i;    int a,x,y;    int x1,y1,x2,y2,x3,y3;    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&a,&x,&y);        if(tp(a,x,y))        {            x1=find(x),y1=find(y);            x2=find(x+n),y2=find(y+n);            x3=find(x+2*n),y3=find(y+2*n);            if(a==1)            {                if(x1==y2||x1==y3)                 {                    cnt++;                    continue;                    }                else                 {                    merge(x1,y1);                    merge(x2,y2);                    merge(x3,y3);                }               }            else             {                if(x1==y1||x1==y2)                 {                    cnt++;                    continue;                }                else                 {                    merge(x3,y2);                    merge(x2,y1);                    merge(x1,y3);                }            }        }        else cnt++;    }    printf("%d",cnt);    return 0;}
原创粉丝点击