zoukankan      html  css  js  c++  java
  • Going from U to V or from V to U?

    【题目描述】

    现给定一幅有向图,选择两个点V和U,要求V能到达U或U能到达V。

    询问对于图中的每一点对(V,U)是否都能满足条件,如果可以,输出“Yes”,否则,输出“No”。

    【输入描述】

    第一行输入一个正整数T,表示数据组数;

    接下来输入T组数据,每组数据输入格式如下:

    第一行输入两个整数n、m(0 < n < 1001,m < 6000),分别表示节点数和边数;

    接下来m行,每行输入两个整数U、V,表示节点U和节点V之间存在一条有向边。

    【输出描述】

    对于每组输入数据,输出一行,包含一个“Yes”或“No”。

    【输入样例】

    1

    3 3

    1 2

    2 3

    3 1

    【输出样例】

    Yes

    源代码:
    
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<stack>
    #include<queue>
    using namespace std;
    vector <int> List[1001],Edge[1001];
    stack <int> S;
    queue <int> Q;
    int T,n,m,Num,Number,i[1001],j[1001],Head[1001],InSum[1001];
    bool In[1001];
    void Tarjan(int T) //朴素Tarjan。
    {
        i[T]=j[T]=++Num;
        S.push(T);
        In[T]=true;
        for (int a=0;a<List[T].size();a++)
        {
            int t=List[T][a];
            if (!j[t])
            {
                Tarjan(t);
                i[T]=min(i[T],i[t]);
            }
            else
              if (In[t])
                i[T]=min(i[T],j[t]);
        }
        if (i[T]==i[T])
        {
            int k;
            Number++; 
            do
            {
                k=S.top();
                Head[k]=Number;
                In[k]=false;
                S.pop();
            }
            while (T!=k);
        }
    }
    bool Topsort() //拓扑排序。
    {
        int Count(0);
        while (!Q.empty())
          Q.pop();
        for (int a=1;a<=Number;a++)
          if (!InSum[a])
          {
            Count++;
            Q.push(a);
          }
        if (Count-1)
          return false; //存在一个以上入度为0的点,注意这是在求单连通分量。
        while (!Q.empty()) //涨姿势了,利用队列实现。
        {
            int T=Q.front();
            Q.pop();
            Count=0;
            for (int a=0;a<Edge[T].size();a++)
            {
                int t=Edge[T][a];
                InSum[t]--;
                if (!InSum[t])
                {
                    Count++;
                    Q.push(t);
                }
            }
            if (Count-1)
              return false; //同理于上。
        }
        return true;
    }
    void Solve()
    {
        for (int a=1;a<=n;a++)
          if (!j[a])
            Tarjan(a);
        memset(InSum,0,sizeof(InSum)); //InSum[]存储缩点后的入度数。
        for (int a=1;a<=Number;a++) //这么多初始化真是,想婊人。
          Edge[a].clear();
        for (int a=1;a<=n;a++)
          for (int b=0;b<List[a].size();b++) //缩点重新建图。
          {
            int t1=Head[a];
            int t2=Head[List[a][b]];
            if (t1!=t2)
            {
                InSum[t2]++;
                Edge[t1].push_back(t2);
            }
          }
        if (Topsort())
          printf("Yes
    ");
        else
          printf("No
    ");
    }
    int main() //Tarjan缩点+拓扑排序。
    {
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d%d",&n,&m);
            Num=Number=0; //Num表示Tarjan序编号,Number表示缩点后的点数。
            while (!S.empty()) //Tarjan栈。
              S.pop();
            for (int a=1;a<=n;a++)
            {
                List[a].clear(); //初始图。
                j[a]=In[a]=0; //j[]存储时间戳,In[]表示是否入Tarjan栈。
            }
            while (m--)
            {
                int t1,t2;
                scanf("%d%d",&t1,&t2);
                List[t1].push_back(t2);
            }
            Solve();
        }
        return 0;
    }
  • 相关阅读:
    shell28获取命令结果的第几个参数
    在 Amazon EC2 Linux 实例上手动安装 SSM 代理 Raspbian
    Trying out the Intel Neural Compute Stick 2 – Movidius NCS2
    Flask
    virtualenv/venv 和 pip
    轻量化卷积神经网络:SqueezeNet、MobileNet、ShuffleNet、Xception
    向 AWS Elastic Beanstalk 部署 Flask 应用程序
    Installing the AWS Toolkit for Visual Studio Code
    Installing the AWS SAM CLI on macOS
    树莓派显示器电源管理禁止屏幕休眠
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5930510.html
Copyright © 2011-2022 走看看