zoukankan      html  css  js  c++  java
  • poj 2762 强连通缩点+拓扑排序

    这题搞了好久,先是拓扑排序这里没想到,一开始自己傻乎乎的跑去找每层出度为1的点,然后才想到能用拓扑排序来弄。

    拓扑排序的时候也弄了挺久的,拓扑排序用的也不多。

    题意:给一个图求是否从对于任意两个点能从v 到w 或者从w到v连通。

    思路:单连通,先强连通缩点,若scnt为1,或者出度为零的点为0,直接输出YES,若出度为零的点大于1,则代表有分支输出NO。若出度为零的点为1,判断组成的树是否为单链,即没有分支,用拓扑排序即可。

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define MAXN 1100
    #define MAXM 6600
    struct Edge
    {
        int to,next;
    
    }edge[MAXM];
    
    int first[MAXN], stack[MAXN], DFN[MAXN], Low[MAXN], Belong[MAXN];
    int indegree[MAXN],instack[MAXN];
    int n,m,tot,scnt,top,cnt;
    bool new_map[MAXN][MAXN];int vis[MAXN];
    
    void Tarjan(int v)
    {
        int min,t;
        DFN[v]=Low[v]=++tot;
        instack[v]=1;
        stack[top++]=v;
        for(int e=first[v];e!=-1;e=edge[e].next)
        {
            int j=edge[e].to;
            if(!DFN[j])
            {
                Tarjan(j);
                if(Low[v]>Low[j])Low[v]=Low[j];
            }
            else if(instack[j]&&DFN[j]<Low[v])
            {
                Low[v]=DFN[j];
            }
        }
        if(DFN[v]==Low[v])
        {
            scnt++;
            do
            {
                t=stack[--top];
                instack[t]=0;
                Belong[t]=scnt;
            }while(t!=v);
        }
    }
    void read_graph(int v,int w)
    {
        edge[tot].to=w;
        edge[tot].next=first[v];
        first[v]=tot++;
    }
    void solve()
    {
        for(int i=1;i<=n;i++)
            if(!DFN[i])
                Tarjan(i);
    }
    void process(int j,int n)
    {
        for(int i=1;i!=n+1;i++)
        {
            if(new_map[j][i])
                indegree[i]--;
        }
    }
    int check(int n)
    {
        int count(0);
        int t(0);
        for(int i=1;i!=n+1;i++)
        {
            if(vis[i]==false&&indegree[i]==0)
            {
                t=i;
                vis[i] = true;
                count++;
            }
        }
        if(t!=0)
            process(t,n);
        return count;
    }
    bool topo_sort(int n)
    {
        memset(vis,false,sizeof(vis));
        for(int i=1;i!=n+1;i++)
        {
            if(check(n)>1)
                return false;
        }
        return true;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(indegree,0,sizeof(indegree));
            memset(DFN,0,sizeof(DFN));
            memset(first,-1,sizeof(first));
            cnt=scnt=tot=top=0;
    
            memset(new_map,false,sizeof(new_map));
    
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                int v,w;
                scanf("%d%d",&v,&w);
                read_graph(v,w);
            }
            solve();
            //cout<<scnt<<endl;
            if(scnt==1)
            {
                printf("Yes
    ");
                continue;
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=first[i];j!=-1;j=edge[j].next)
                {
                    int v=edge[j].to;
                    if(Belong[i]!=Belong[v])
                        {
                            new_map[Belong[i]][Belong[v]] = true;
                            indegree[Belong[v]]++;
                        }
                }
            }
            int count1=0;
            for(int i=1;i<=scnt;i++)
            {
                if(indegree[i]==0)
                    count1++;
            }
            if(count1==0)
            {
                printf("Yes
    ");
                continue;
            }
            else if(count1>1)
            {
                printf("No
    ");
                continue;
            }
            if(topo_sort(scnt))
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
    


     

  • 相关阅读:
    命令行推送文章到博客园
    链表的新写法
    关于vim无法复制到剪切板的问题
    Ethernet & ARP Protocol
    [从今天开始修炼数据结构]串、KMP模式匹配算法
    [从今天开始修炼数据结构]队列、循环队列、PriorityQueue的原理及实现
    [从今天开始修炼数据结构]栈、斐波那契数列、逆波兰四则运算的实现
    [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList
    IntelliJ IDEA快捷键大全
    [从今天开始修炼数据结构]基本概念
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134126.html
Copyright © 2011-2022 走看看