[HDU] 3342 Legal or Not-简单建模后深搜,检测回边的存在

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3342

方法:把所有master-prentice的关系都看一条以master为起点prentice为终点的有向边来建立有向图,然后检测有向图中是不是存在回边。检测的方法是通过染色的白灰黑方式进行深搜,看有没有出现回边,搜索过过程中,如果通过一个边探索到了灰色的点,则该边为回边。具体参考《算法导论》一书上的相关定理证明。

感想:简单题目,但后期需要频繁重温代码。

代码:

 

#include<iostream>
#include<queue>
using namespace std;
bool matrix[101][101];
enum NodeColor{White,Gray,Black};
NodeColor color[101];
struct Arc
{
    int node;
    Arc*  nextArc;
};
struct Node
{
    Arc*  firstArc;
};
Node* nodes[101];
void createArc(int x,int y)
{
    Arc* arc = (Arc*)malloc(sizeof(Arc));
    arc->node = y;
    if(nodes[x]->firstArc == NULL)
            arc->nextArc = NULL;
    else
        arc->nextArc = nodes[x]->firstArc;
    nodes[x]->firstArc = arc;
}

bool DFSValidate(int root)
{
    bool valid = true;
    if(color[root] ==  White)
    {
        color[root] = Gray;
        Arc* t_arc = nodes[root]->firstArc;
        while(t_arc!=NULL)
        {
            if(color[t_arc->node] ==  Gray)
            {
                valid = false;
                break;
            }
            else if(color[t_arc->node] == White)
            {
                if(!DFSValidate(t_arc->node))
                {
                    valid = false;
                    break;
                }
            }
            t_arc = t_arc->nextArc;
        }
        color[root]=Black;
    }
    return valid;
}
int main()
{
    int n,m;
    while(scanf("%d %d", &n, &m) == 2 && n!=0)
    {
        int i = 0;
        bool valid = true;
        for(i=0;i<n;i++)
        {
            nodes[i] = (Node*)malloc(sizeof(Node));
            nodes[i]->firstArc = NULL;
            color[i] = White;
        }
        int a,b;
        i=0;
        memset(matrix,false,sizeof(matrix));
        while(i<m)
        {
            scanf("%d %d",&a,&b);
            if(a!=b && matrix[a][b]==false)
            {
                matrix[a][b]=true;
                createArc(a,b);
            }
            i++;
        }
        for(int i=0;i<n;i++)
        {
            if(DFSValidate(i)==false)
            {
                valid =false;
                break;
            }
        }
        if(valid)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
} 

 

posted @ 2013-04-13 17:58  kbyd  阅读(184)  评论(0编辑  收藏  举报