• poj Going from u to v or from v to u?


    题意找 一个图是否 任意两点都可以从 u 到v  或者 从v到u   注意是或者 所以不是一个简单的强连通图

    思路 :  先找出这个图的  强连通分量 在强连通分量里任意两点都是可以互相到达的 再看 缩点后 在拓扑排序时是否入度为0 的点一直会《=1  若中间有一步 发现入度为0 的点>=2 就直接可以判断这两个点 热河一个点都到达不了对方  应该输出 no

    代码有点长 再次提醒自己 细心!

    #include<iostream>
    #include<vector>
    #include<string.h>
    #include<stack>
    using namespace std;
    
    int pre[1002],low[1002],c,sccnum[1002],degree[1002],scc,n;
    vector <int > g[1002],gg[1002];
    stack <int > s;
    
    int min(int a,int b)
    {
        return a<b?a:b;
    }
    int dfs(int u)
    {
        s.push (u);
        low[u]=pre[u]=c++;
        for(int i=0;i<g[u].size ();i++)
        {
            int v=g[u][i];
            if(!pre[v])
            {
                int lowv=dfs(v);
                low[u]=min(low[u],lowv);
            }
            else if(sccnum[v]==0)
                low[u]=min(low[u],pre[v]);
        }
        if(pre[u]==low[u])
        {
            scc++;
            while(1)
            {
                int t=s.top (); s.pop();
                sccnum[t]=scc;
                if(u==t)
                    break;
            }
        }
        
        return low[u];
    }
    
    int solve()
    {
        int i,j,cur;
        for(i=1;i<=scc;i++)
            gg[i].clear ();  //注意这里 两个容器不要搞混了。。
        memset(degree,0,sizeof(degree));
        for(i=1;i<=n;i++)
            for(j=0;j<g[i].size ();j++)
            {
                int v=g[i][j];
                if(sccnum[i]!=sccnum[v])
                {
                    degree[sccnum[v]]++;   //入度
                    gg[sccnum[i]].push_back (sccnum[v]);
                }                       //记录每个缩点的 入度
            }
            int cnt=0;
        for(i=1;i<=scc;i++)
            if(degree[i]==0)
            {
                cnt++;
                cur=i;
                if(cnt>1)    //一旦在某一步发现 入度为0 的 点超过了1  就直接跳出
                    return 0;
            }
            int num=scc,temp=-1;
            while(num--)  //
            {
                cnt=0;
                for(i=0;i<gg[cur].size ();i++)
                {
                    int v=gg[cur][i];
                    degree[v]--;
                    if(degree[v]==0)
                    {
                        cnt++;
                        if(cnt>1)
                            return 0;
                        temp=v;
                    }                
                }
                cur=temp;
            }
            return 1;
    }
    
    
    
    
    
    int main()
    {
        int t,m,a,b,i,p=1;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(i=1;i<=n;i++)
                g[i].clear();
            while(m--)
            {
                scanf("%d%d",&a,&b);
                g[a].push_back (b);
            }
            memset(pre,0,sizeof(pre));
            memset(sccnum,0,sizeof(sccnum));
            int cnt=0;  c=1; scc=0;
            
            for(i=1;i<=n;i++)            
                if(!pre[i])
                    dfs(i);//printf("ok
    ");
    
                int ww=solve();        
                if(ww==0)
                    printf("No
    ");
                else
                    printf("Yes
    ");
                
        }
        return 0;
    }
  • 相关阅读:
    Numpy入门
    Numpy入门
    Spring源码之IoC原理
    LeetCode之连续子数组的最大和
    剑指Offer之从1到n整数中1出现的次数
    剑指Offer之最小的k个数
    剑指Offer之字符串的排列
    剑指Offer之二叉搜索树与双向链表
    剑指Offer之二叉树中和为某一值的路径
    剑指Offer之二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/assult/p/3257894.html
Copyright © 2020-2023  润新知