zoukankan      html  css  js  c++  java
  • ZOJ 3811 Untrusted Patrol【并查集】

    题目大意:给一个无向图,有些点有装监视器记录第一次到达该点的位置,问是否存在一条路径使得监视器以给定的顺序响起,并且经过所有点

    思路:牡丹江网络赛的题,当时想了种并查集的做法,通神写完程序WA了几发,此时JYB用BFS秒了,索性最后还是调出来了,今天自己写了下,感觉唯一的坑点就是需要遍历完所有的点

    //zoj3811

    #include <stdio.h>

    #include <string.h>

    #include <algorithm>

    #include <queue>

    #define maxn 500000

    #define inf 0x3f3f3f3f

    using namespace std;

    int father[maxn],head[maxn],point[maxn],next[maxn];

    int n,m,k,a,b[maxn],now,x[maxn],y[maxn];

    bool mark[maxn];

    int find(int x)

    {

        if(father[x]==x)return x;

        return father[x]=find(father[x]);

    }

    void add(int x,int y)

    {

        next[++now]=head[x];

        head[x]=now;

        point[now]=y;

    }

    int main()

    {

        int t,xx,yy,l;

        scanf("%d",&t);

        while(t--)

        {

            int flag=0,z=0;

            now=0;

            memset(head,0,sizeof(head));

            memset(mark,0,sizeof(mark));

            scanf("%d%d%d",&n,&m,&k);

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

            for(int i=1;i<=k;i++)

            {

                scanf("%d",&a);

                mark[a]=1;

            }

            for(int i=1;i<=m;i++)

            {

                scanf("%d%d",&xx,&yy);

                add(xx,yy);add(yy,xx);

                x[i]=xx;y[i]=yy;

            }

            scanf("%d",&l);

            for(int i=1;i<=l;i++)scanf("%d",&b[i]);

            mark[b[1]]=0;

            //if(l!=k){printf("No ");continue;}

            for(int i=1;i<=m;i++)

            {

                if(mark[x[i]]||mark[y[i]])continue;

                xx=find(x[i]);yy=find(y[i]);

                if(xx!=yy)

                {

                    father[xx]=yy;

                    z++;

                 //   printf("%d  %d",x[i],y[i]);

                }

            }

            for(int i=2;i<=l;i++)

            {

                mark[b[i]]=0;

                for(int j=head[b[i]];j;j=next[j])

                {

                    int u=point[j];

                    if(mark[u]==1)continue;

                    xx=find(b[i]);yy=find(u);

                    if(xx!=yy){father[xx]=yy;z++;}

                }

                xx=find(b[i]);yy=find(b[i-1]);

                if(xx!=yy)

                {

                    flag=1;break;

                }

            }

            for(int i=1;i<=n;i++)if(find(i)!=find(b[1]))flag=1;

            if(flag==1)printf("No ");

            else printf("Yes ");

        }

        return 0;

    }

  • 相关阅读:
    【初心】
    【杂题集】单题小总结
    【模板】(旧)矩阵模板
    【机智题?】【Vijos】【天平称量】
    【杂题集】【51NOD 1267】4个数和为0
    【模板】(旧)Miller Rabin 素数判定
    【杂谈】只是想想
    【杂谈】思考
    【学习?】组合和排序
    【模版】读入优化
  • 原文地址:https://www.cnblogs.com/philippica/p/4114410.html
Copyright © 2011-2022 走看看