zoukankan      html  css  js  c++  java
  • hoj 3005 Game Rigging 强联通分量求缩点

    /*

    题目:

        现给出各位选手的能力比较并给出自己的朋友的参赛号码,如何组织比赛使得自己的朋友能够获胜

    分析:

        各选手能力比较可以构造一个有向图,而想要使得自己的朋友要赢得比赛,所以他的所在的连通块

        必定是入度为0的(假设建图时是以能力大的人作为边的起点)。所以题目可以转换为先建图,然后

        再找连通块求缩点,然后判断该缩点是否入度为0,若有朋友在该连通块中,即可判断可以组织这样

        的一场比赛。而判断朋友在不在该连通块中,可以先求到所有的入度为0的连通块用数组置为true,

        然后直接把所有朋友的所在的连通块置为false,若所有的连通块中只要还有true的连通块,就可判断

        不能组织这样的一场比赛

    */

    #include <cstdio>

    #include <cstring>

    const int X = 100005;

    int dfn[X],low[X],stack[X],deg[X],father[X],depth,top,bcnt;

    int f[X],fri,n,m;

    bool use[X],instack[X];

    struct node

    {

        int v;

        node *next;

        void fun()

        {

            v = 0;

            next = NULL;

        }

    }edge[X],*head[X],*tmp;

    void tarjan(int u)

    {

        int v;

        dfn[u] = low[u] = ++depth;

        stack[++top] = u;

        instack[u] = true;

        for(node *p=head[u];p;p=p->next)

        {

            v = p->v;

            if(!low[v])

            {

                tarjan(v);

                if(low[v]<low[u])

                    low[u] = low[v];

            }

            else if(instack[v]&&low[u]>dfn[v])

                low[u] = dfn[v];

        }

        if(low[u]==dfn[u])

        {

            bcnt++;

            do

            {

                v = stack[top--];

                instack[v] = false;

                father[v] = bcnt;

            }while(u!=v);

        }

    }

    void solve()

    {

        memset(instack,false,sizeof(instack));

        memset(low,0,sizeof(low));

        memset(deg,0,sizeof(deg));

        depth = bcnt = top = 0;

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

            if(!low[i])

                tarjan(i);

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

            for(node *p=head[i];p;p=p->next)

                if(father[i]!=father[p->v])

                    deg[father[p->v]]++;

        memset(use,false,sizeof(use));

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

            if(!deg[i])

                use[i] = true;

        for(int i=0;i<fri;i++)

            use[father[f[i]]] = false;

        bool flag = true;

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

            if(use[i])

            {

                flag = false;

                break;

            }

        flag?printf("yes\n"):printf("no\n");

    }

    int main()

    {

        freopen("sum.in","r",stdin);

        freopen("sum.out","w",stdout);

        while(scanf("%d%d%d",&n,&fri,&m),n||m||fri)

        {

            for(int i=0;i<fri;i++)

                scanf("%d",&f[i]);

            memset(head,NULL,sizeof(head));

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

                edge[i].fun();

            tmp = edge;

            int u,v;

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

            {

                scanf("%d%d",&u,&v);

                tmp->next = head[u];

                tmp->v = v;

                head[u] = tmp++;

            }

            solve();

        }

        return 0;

    }

  • 相关阅读:
    运算符(C# 参考)
    virtualbox修改主机名
    偏前端HTML5 sessionStorage会话存储
    偏前端纯css,手写轮播(焦点切换 和 自动轮播 只可选择一种,两者不可共存)
    偏前端 div+mui+vue.js 制作问卷调查单页 ——题目答案由后台随机给出10道
    偏前端 jqueryiframe内触发父窗口自定义事件
    TWAIN扫描打印图像编辑处理控件ImagXpress功能大全
    实时温度计湿度计高效仪器控件Iocomp使用教程
    Essential Diagram for Windows Forms绘图控件图解及下载地址
    Code39 Fontware条形码控件
  • 原文地址:https://www.cnblogs.com/yejinru/p/2507973.html
Copyright © 2011-2022 走看看