大意:判断是否有向图是否有环。

 

思路1:通过Floyd传递闭包来确定是否有向环。(350MS)

思路2:通过拓扑排序判断是否存在有向环。(109MS)

CODE1:

 

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

const int SIZE = 510;

int G[SIZE][SIZE];
int n, m;

int FLoyd()
{
    for(int k = 0; k < n; k++)
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)    G[i][j] = G[i][j] ||(G[i][k] && G[k][j]);
            //if(G[i][k] && G[k][j]) G[i][j] = 1;
    for(int i = 0; i < n; i++)
        if(G[i][i] == 1return 0;            //存在环
    return 1;
}

void init()
{
    memset(G, 0sizeof(G));
}
int main()
{
    while(~scanf("%d%d", &n, &m), n, m)
    {
        init();
        while(m--)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            G[u][v] = 1;
        }
        if(FLoyd())
        {
            printf("YES\n");
        }
        else printf("NO\n");
    }
    return 0;
}

 

CODE2:

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

const int SIZE = 510;

int G[SIZE][SIZE];
int topo[SIZE], ind[SIZE];
int n, m;

int toposort()
{
    for(int i = 0; i < n; i++)
    {
        int u;
        for(u = 0;  u < n; u++)
            if(!ind[u]) break;
        if(u >= n) return 0;
        topo[i] = u; ind[u]--;
        for(int v = 0; v < n; v++)
             if(G[u][v]) ind[v]--;
    }
    return 1;
}

void init()
{
    memset(ind, 0sizeof(ind));
    memset(topo, 0sizeof(topo));
    memset(G, 0sizeof(G));
}

int main()
{
    while(~scanf("%d%d", &n, &m), n, m)
    {
        init();
        while(m--)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            if(!G[u][v])
            {
                G[u][v] = 1;
                ind[v]++;
            }
        }
        if(toposort())
        {
            printf("YES\n");
        }
        else printf("NO\n");
    }
    return 0;
}

 

posted on 2012-09-18 11:18  有间博客  阅读(172)  评论(0编辑  收藏  举报