題目:
Problem Description
In reward of being yearly outstanding magic student, Harry gets a magical computer. When the computer begins to deal with a process, it will work until the ending of the processes. One day the computer got n processes to deal with. We number the processes from 1 to n. However there are some dependencies between some processes. When there exists a dependencies (a, b), it means process b must be finished before process a. By knowing all the m dependencies, Harry wants to know if the computer can finish all the n processes.
Input
There are several test cases, you should process to the end of file.For each test case, there are two numbers n m on the first line, indicates the number processes and the number of dependencies. 1≤n≤100,1≤m≤10000
The next following m lines, each line contains two numbers a b, indicates a dependencies (a, b). 1≤a,b≤n
Output
Output one line for each test case. If the computer can finish all the process print "YES" (Without quotes).Else print "NO" (Without quotes).
Sample Input
3 2
3 1
2 1
3 3
3 2
2 1
1 3
Sample Output
YES
NO
根據(jù)題目意思暮芭,可以知道此題為拓?fù)渑判颉?br> 此題會(huì)出現(xiàn)一種情況:環(huán)耸别。因?yàn)橥負(fù)渑判蛞蟠藞D是有向無(wú)環(huán)圖,因此如果有環(huán),肯定不能拓?fù)渑判颍ㄝ敵鯪O),如果能用拓?fù)渑判颍瑒t輸出YES.
由于拓?fù)渑判蛎看味颊业饺攵葹?的點(diǎn),然后入隊(duì)列維護(hù)。如果此有向圖有環(huán)峭范,必然存在入度無(wú)法減為0的點(diǎn),因此可以統(tǒng)計(jì)最終出隊(duì)列的個(gè)數(shù)是否為n.
參考代碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
const int MAVE = 10000+10;
const int MAXV = 100+10;
using namespace std;
struct edge {
int next,to;
} e[MAVE];
int head[MAXV],tot;
void init() {
memset(head,-1,sizeof(head));
tot = 0;
}
void add_edge(int a,int b) {
e[tot].next = head[a];
e[tot].to = b;
head[a] = tot++;
}
int n,m;
int din[MAXV];
bool topo() {
queue<int> que;
for (int i = 1;i <= n;++i) {
if (din[i] == 0) que.push(i);
}
int cnt = 0;
while (!que.empty()) {
int u = que.front();
que.pop();
for (int i = head[u];i != -1;i = e[i].next) {
int v = e[i].to;
--din[v];
if (din[v] == 0) {
que.push(v);
}
}
cnt++;
}
if (cnt == n) {
return true;
}
else return false;
}
int main() {
while (scanf("%d%d", &n, &m) != EOF) {
init();
memset(din,0,sizeof(din));
int a,b;
for (int i = 1;i <= m;++i) {
scanf("%d%d", &a, &b);
add_edge(a,b);
din[b]++;
}
if (topo()) printf("YES\n");
else printf("NO\n");
}
return 0;
}