zoukankan      html  css  js  c++  java
  • poj 2762(tarjan缩点+判断是否是单链)

                                  Going from u to v or from v to u?
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 19234   Accepted: 5182

    Description

    In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

    Input

    The first line contains a single integer T, the number of test cases. And followed T cases. 

    The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly. 

    Output

    The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.

    Sample Input

    1
    3 3
    1 2
    2 3
    3 1
    

    Sample Output

    Yes

    题意:给你一个有向图 判断任意两点是否能够到达

    先缩点 然后判断是否是一棵单直链  拓扑排序就可以 每次判断队列中的点是否只有一个就可以

    就是每次入度为0的点只有一个 

    #include<iostream>//HiHo 1515
    #include<cstdio>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<cstring>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<vector>
    #include<algorithm>
    #include<string.h>
    typedef long long ll;
    typedef unsigned long long LL;
    using namespace std;
    const int INF=0x3f3f3f3f;
    const double eps=0.0000000001;
    const int N=10000+10;
    struct node{
        int to,next;
    }edge[N<<1];
    int tot;
    int head[N];
    int belong[N];
    int dfn[N],low[N];
    int cnt;
    int vis[N];
    int num;
    vector<int>vc[N];
    void init(){
        memset(head,-1,sizeof(head));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<N;i++)vc[i].clear();
        tot=0;
        num=0;
        cnt=0;
    }
    void add(int u,int v){
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    stack<int>st;
    void tarjan(int u){
        low[u]=dfn[u]=++num;
        vis[u]=1;
        st.push(u);
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(dfn[v]==0){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(vis[v]){
                low[u]=min(low[u],dfn[v]);
            }
        }
        if(low[u]==dfn[u]){
            int vv;
            cnt++;
            do{
                vv=st.top();
                st.pop();
                belong[vv]=cnt;
                vis[vv]=0;
            }while(vv!=u);
        }
    }
    queue<int>q;
    int in[N];
    void tuposort(){
        while(q.empty()==0){
            if(q.size()!=1){
                cout<<"No"<<endl;
                return;
            }
            int u=q.front();
            q.pop();
            for(int i=0;i<vc[u].size();i++){
                int v=vc[u][i];
                in[v]--;
                if(in[v]==0){
                    q.push(v);
                }
            }
        }
        cout<<"Yes"<<endl;
        return;
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            int n,m;
            init();
            while(q.empty()==0)q.pop();
            memset(in,0,sizeof(in));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                int u,v;
                scanf("%d%d",&u,&v);
                add(u,v);
            }
            for(int i=1;i<=n;i++){
                if(dfn[i]==0)tarjan(i);
            }
            //for(int i=1;i<=n;i++)cout<<belong[i]<<" ";cout<<endl;
            for(int i=1;i<=n;i++){
                for(int j=head[i];j!=-1;j=edge[j].next){
                    int uu=belong[i];
                    int vv=belong[edge[j].to];
                    if(uu!=vv){
                        vc[uu].push_back(vv);
                       // cout<<uu<<" "<<vv<<endl;
                        in[vv]++;
                    }
                }
            }
            for(int i=1;i<=cnt;i++){
                if(in[i]==0){
                    q.push(i);
                }
            }
            tuposort();
        }
    }
    

      

  • 相关阅读:
    合数分解为质数的乘积模板
    P2626 斐波那契数列(升级版)(合数的质数分解, 大数为素数的概率十分小的利用)
    1305 Pairwise Sum and Divide
    1344 走格子 (前缀和)
    1347 旋转字符串
    E
    pek (北大oj)3070
    数学中各种矩阵收集(转至其他博主)
    (数论)逆元的线性算法
    洛谷P2627 修剪草坪 题解 单调队列优化DP
  • 原文地址:https://www.cnblogs.com/Aa1039510121/p/9145569.html
Copyright © 2011-2022 走看看