ZZUOJ 1199 大小关系(拓扑排序,两种方法_判断入度和dfs回路判断)

简介:

/*
  这道题如果按照度为0的节点来判断的时候,将度为0的节点和其相连的节点(度数并减去1) 
  从图中去掉,如果度为0的节点的个数为0个但是图中的节点没有都去掉的   时候那么说明
  出现了回路!用这种方法必须将重边去除掉! 
  
  所以推荐用dfs方式进行判断!这种方式还是比较直观的! 
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

int used[30];
int deg[30];
int map[30][30];
int sum;
bool topoSort(){
    for(int i=1; i<=sum; ++i){
        int cnt=0, p;
        for(int j=0; j<26; ++j)
           if(used[j] && deg[j]==0) {
              ++cnt;
              p=j;
           }
        if(cnt==0) return false;
        for(int j=0; j<26; ++j)
           if(map[p][j]){
               map[p][j]=0;
               --deg[j];
           } 
        deg[p]=-1;
    }
    return true;
}

int main(){
    int m;
    char ch[5];
    while(cin>>m){
        memset(used, 0, sizeof(used));
        memset(deg, 0, sizeof(deg));
        memset(map, 0, sizeof(map));
        while(m--){
           cin>>ch;           
           used[ch[0]-'A'] =1;
           used[ch[2]-'A'] =1;
           if(ch[1]=='>'){
               if (map[ch[2]-'A'][ch[0]-'A'] != 1) {//去掉多重边 
               ++deg[ch[0]-'A'];
               map[ch[2]-'A'][ch[0]-'A']=1;
               }
           }
           else{
               if (map[ch[0]-'A'][ch[2]-'A'] != 1) {
               ++deg[ch[2]-'A'];
               map[ch[0]-'A'][ch[2]-'A']=1;
            }
          }
        }
        sum=0;
        for(int i=0; i<26; ++i)
           if(used[i])  ++sum;
        if(topoSort())
           cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
} 

*/

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int map[30][30];
int vis[30]; 

bool dfs(int cur){
    vis[cur]=-1;
    for(int i=0; i<26; ++i)
       if(map[cur][i]){
          if(vis[i]==-1) return false;
          if(!vis[i] && !dfs(i)) return false;
       }
    vis[cur]=1;
    return true;
}

int main(){
    int m;
    char ch[5];
    while(cin>>m){
        memset(vis, 0, sizeof(vis)); 
        memset(map, 0, sizeof(map));
        while(m--){
            cin>>ch;
            if(ch[1]=='>')
               map[ch[2]-'A'][ch[0]-'A']=1;
            else
               map[ch[0]-'A'][ch[2]-'A']=1;
        }
        int flag=0;
        for(int i=0; i<26; ++i)
           if(!vis[i])
             if(!dfs(i)){
                flag=1;
                break;
             }
        if(flag)  cout<<"NO"<<endl;
        else cout<<"YES"<<endl; 
    }    
    return 0;
}

目录
相关文章
【图论】【深度优先搜索】【换根法】2858. 可以到达每一个节点的最少边反转次数
【图论】【深度优先搜索】【换根法】2858. 可以到达每一个节点的最少边反转次数
|
9月前
|
算法 测试技术 C#
【图论 状态压缩 枚举】2959. 关闭分部的可行集合数目
【图论 状态压缩 枚举】2959. 关闭分部的可行集合数目
|
9月前
|
算法 NoSQL 容器
状态定义与深度优先搜索、广度优先搜索
状态定义与深度优先搜索、广度优先搜索
|
算法 测试技术 C#
C++深度优先搜索(DFS)算法的应用:树中可以形成回文的路径数
C++深度优先搜索(DFS)算法的应用:树中可以形成回文的路径数
|
人工智能 算法 BI
C++深度优先搜索的应用:在树上执行操作以后得到的最大分数
C++深度优先搜索的应用:在树上执行操作以后得到的最大分数
|
算法
代码随想录算法训练营第十八天 | 力扣 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
代码随想录算法训练营第十八天 | 力扣 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
66 0
|
存储 算法
算法训练Day18|● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
算法训练Day18|● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
|
数据采集 算法 C++
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
1336 0
|
定位技术
DFS:迷宫解的方案数
DFS:迷宫解的方案数
106 0
|
算法 Java
【算法】字符串复原IP地址,从前序与中序编辑序列构造二叉树 三道算法题
字符串复原IP地址,从前序与中序编辑序列构造二叉树
139 1
【算法】字符串复原IP地址,从前序与中序编辑序列构造二叉树 三道算法题

热门文章

最新文章