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;
}
原文地址:https://www.cnblogs.com/assult/p/3257894.html