大意不再赘述。
思路:可以通过两种方法去判断是否有环,Floyd或者拓扑排序。
拓扑排序时,由于不需要输出,所以邻接表不需要考虑重边的情况,邻接矩阵就需要判重边。
Floyd:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 110;
int d[MAXN][MAXN];
int n, m;
void init()
{
memset(d, 0, sizeof(d));
}
void Floyd()
{
for(int k = 0; k < n; k++)
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
d[i][j] = d[i][j] || (d[i][k] && d[k][j]);
}
}
}
for(int i = 0; i < n; i++) if(d[i][i])
{
printf("NO\n");
return ;
}
printf("YES\n");
}
int read_case()
{
init();
scanf("%d%d", &n, &m);
if(!n && !m) return 0;
while(m--)
{
int i, j;
scanf("%d%d", &i, &j);
d[i][j] = 1;
}
return 1;
}
void solve()
{
Floyd();
}
int main()
{
while(read_case())
{
solve();
}
return 0;
}
toposort:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 110;
const int MAXM = 110*110;
struct Edge
{
int v, next;
}edge[MAXM];
int first[MAXN], topo[MAXN];
int ind[MAXN];
int n, m;
int cnt;
inline void init()
{
cnt = 0;
memset(first, -1, sizeof(first));
memset(ind, 0, sizeof(ind));
}
inline void read_graph(int u, int v)
{
edge[cnt].v = v;
edge[cnt].next = first[u], first[u] = cnt++;
}
int toposort()
{
queue<int> q;
int tot = 0;
for(int v = 0; v < n; v++) if(!ind[v]) q.push(v);
while(!q.empty())
{
int x = q.front(); q.pop();
topo[++tot] = x;
for(int e = first[x]; e != -1; e = edge[e].next)
{
int v = edge[e].v;
if(--ind[v] == 0)
{
q.push(v);
}
}
}
if(tot != n) return 0;
return 1;
}
inline int read_case()
{
init();
scanf("%d%d", &n, &m);
if(!n && !m) return 0;
while(m--)
{
int u, v;
scanf("%d%d", &u, &v);
read_graph(u, v);
ind[v]++;
}
}
void solve()
{
printf(toposort()? "YES\n":"NO\n");
}
int main()
{
while(read_case())
{
solve();
}
return 0;
}