zoukankan      html  css  js  c++  java
  • poj 2762 Going from u to v or from v to u?(tarjan缩点+拓扑排序)

    题目链接:http://poj.org/problem?id=2762

    题目意思:一个山洞有n个房间,m条单向边,要任意两个房间(假如房间x,y),要x可以到y,或者y到x(或者不是并且)

    如果可以就输出Yes,不是就输出No。

    思路:题目是或者不是并且,并且的话,直接求是否是强联通图即可。

    或者的话,我们可以这样想本质上是求该图是否为数据结构中单向连通图

    因为可能有环所以要

    1.先用tarjan缩点变成一个DAG(有向无环图)。

    2.再利用拓扑排序的运用,只要每次找入度为0的点时,点的数量不超过一个。

    为什么?我们可以这样想,缩完点的图可以看作一棵树,子树(即入度为0)不可以有两个,因为他们不可以相互到达。

    我想的时候有个错误的想法:(缩完点)不是不能有两个子树吗?那我求每个点的出度,出度为1的点数是点数减一不就是答案吗?还要缩什么点?

    它是个图不是树,说成树是好理解。(缩完点的图)反例:出度为1的点只有1个,但这是一个单向连通图。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn=1e3+100;
    struct node{
        int next,to;
    }edge[maxn*maxn];
    int head[maxn],low[maxn],dfn[maxn],belong[maxn],visit[maxn];
    int in[maxn],st[maxn],n,m,cnt,tot,top,num;
    vector<int> ve[maxn];//记录缩点之后的连接关系 
    queue<int> q;
    void init()//初始化 
    {
        while(!q.empty())
            q.pop();
        memset(head,-1,sizeof(head));
        memset(visit,0,sizeof(visit));//标记是否在栈内 
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low)); 
        memset(belong,0,sizeof(belong));//记录每个点所属于的缩点编号 
        memset(in,0,sizeof(in));//记录每个缩点的入度 
        memset(st,0,sizeof(st));//st模拟栈 
        cnt=tot=top=num=0;
    }
    
    void add(int u,int v)//前向星连边 
    {    
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void tarjan(int u)//tarjan缩点模板 
    {
        dfn[u]=low[u]=++tot;
        visit[u]=1;
        st[++top]=u;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(visit[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u])
        {
            int t;
            num++;//计算缩点的数量 
            do{
                t=st[top--];
                visit[t]=0;
                belong[t]=num;////记录这个点所属于的缩点编号
            }while(t!=u);
        }
    }
    
    bool solve()
    {
        for(int i=0;i<=maxn;i++) 
            ve[i].clear();
        for(int i=1;i<=n;i++)//tarjan缩点 
            if(!dfn[i])
                tarjan(i);
        for(int u=1;u<=n;u++)//寻找每个缩点的关系 
        {
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(belong[u]!=belong[v])//不在一个缩点,那么两个点相连 
                {
                    in[belong[v]]++;//入度 
                    ve[belong[u]].push_back(belong[v]);//记录边的关系 
                }
            }
        }
        //拓扑排序 
        for(int i=1;i<=num;i++)
            if(!in[i])//入度为0的入队列 
                q.push(i);
        if(q.size()>1)//入度为0的个数 
            return false;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=0;i<ve[u].size();i++)
            {
                int v=ve[u][i];
                in[v]--;
                if(!in[v])
                    q.push(v);
            }
            if(q.size()>1)//入度为0的个数 不能同时大于1 
                return false;
        }    
        return true;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            init();
            scanf("%d%d",&n,&m);
            int u,v;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&u,&v);
                add(u,v);
            }
            if(solve())
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
  • 相关阅读:
    面向对象编程思想概览(三)继承
    面向对象编程思想概览(二)封装
    面向对象编程思想概览(一)类和对象
    微软原版WINDOWS10-LTSB-X64位操作系统的全新安装与优化
    IntelliJ IDEA下SVN配置及使用
    Navicat for MySQL导入.sql文件
    IntelliJ IDEA中使用Git
    Git 下载、安装与SSH配置
    Access denied for user 'root'@'localhost' (using password:YES)解决方法
    Navicat for MySQL下载、安装与破解
  • 原文地址:https://www.cnblogs.com/xiongtao/p/10009321.html
Copyright © 2011-2022 走看看