hiho一下 第215周:Circle Detect

描述

You are given a directed graph G which has N nodes and M directed edges. Your task is to detect whether it contains any circle.  

输入

The first line contains an integer T denoting the number of test cases. (1 <= T <= 5)  

For each test case the first line contains two integers N and M. (1 <= N, M <= 100000)  

Then follows M lines. Each contains two integers u and v denoting there is an edge from u to v. (1 <= u, v <= N)

输出

For each test case output "YES" or "NO" denoting whether there is a circle in the graph.

样例输入

2
5 5  
1 2  
2 3  
4 5  
5 4  
4 2
3 2
1 2
2 3

样例输出

YES  
NO 

解题:判断成环的模板题:

  1. 还没被DFS访问的点是白色的,初始时所有点都是白色的
  2. 如果点u已经被DFS访问过,但是u的子节点还未全部被访问到,那么把u染成灰色
  3. 如果点u以及u的子节点都被访问过了,从u回溯到u的父节点时,将u染成黑色

如果在DFS的过程中我们沿着有向边到达了一个灰色节点,则说明图中有环;如果从未到达过灰色节点,说明没有环。

#include <vector>
#include <cstdio>
#include <map>
#include <iostream>
#include <set>
#include <cstring>

using namespace std;
#define MMAX 100000

int color[MMAX + 10]; //1是灰色,0是白色,2是黑色

map<int, vector<int> > mmap;
int dfs(map<int, vector<int> > &mmap, int ma)
{
    int ok = 1;
    color[ma] = 1;
    if (0 == mmap.count(ma)) {
        color[ma] = 2;
        return 1;
    }
    vector<int> prs = mmap[ma];
    for (int i=0; i<prs.size(); ++i) {
        if (0 == color[prs[i]]) {
            ok = dfs(mmap, prs[i]);
            if (!ok) break;
        }
        if (1 == color[prs[i]]) {
            ok = 0;
            break;
        }
    }
    color[ma] = 2;
    return ok;
}

int main()
{
    int N, M,T;
    int ma, pr;
    cin>>T;
    while (T--) {
	    cin >> N >> M;
        for (int i=0; i<M; ++i) {
            cin >> ma >> pr;
            if (0 == mmap.count(ma)) {
                vector<int> prs;
                prs.push_back(pr);
                mmap[ma] = prs;
            }
            else {
                mmap[ma].push_back(pr);
            }
        }
        memset(color, 0, sizeof(color));
        int ok;
        for (map<int, vector<int> >::iterator it = mmap.begin();
                it != mmap.end();
                ++it) {
                    if (0 == color[it->first]) {
                        ok = dfs(mmap, it->first);
                        if (ok == 0) break;
                    }
                }
        if (ok) 
		    cout << "NO" << endl;
        else 
		    cout << "YES" << endl;
        mmap.clear();
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值