題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1269
本題是判斷連通分量個數是否爲1,裸題。
代碼:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 10005;
const int maxm = 100005;
int n, m;
int head[maxn];
struct E {
int to;
int next;
} edge[maxm];
int dfn[maxn];
int low[maxn];
bool instack[maxn];
int stap[maxn];
int index, cur, cnt, eid;
void addedge(int from, int to) {
edge[eid].to = to;
edge[eid].next = head[from];
head[from] = eid ++;
}
void targan(int v) {
if(cnt > 1) return ;
dfn[v] = low[v] = ++index;
instack[v] = true;
stap[++cur] = v;
for (int i = head[v]; ~i; i = edge[i].next) {
int to = edge[i].to;
if(!dfn[to]) {
targan(to);
low[v] = min(low[v], low[to]);
} else if(instack[to]) {
low[v] = min(low[v], dfn[to]);
}
}
if(dfn[v] == low[v]) {
cnt ++;
if(cnt > 1) return ;
int j;
do {
j = stap[cur--];
instack[j] = false;
} while (j != v);
}
}
int main() {
int x, y;
while (~scanf("%d%d", &n, &m), m + n) {
memset(head, -1, sizeof(head));
memset(dfn, 0, sizeof(dfn));
memset(instack, false, sizeof(instack));
eid = 0;
for (int i = 0; i < m; i ++) {
scanf ("%d%d", &x, &y);
addedge(x, y);
}
cur = index = cnt = 0;
for (int i = 1; i <= n; i++) {
if(!dfn[i]) {
targan(i);
if(cnt > 1) break;
}
}
if(cnt == 1) {
printf("Yes\n");
} else {
printf("No\n");
}
}
return 0;
}