题目:http://ac.jobdu.com/problem.php?pid=1448
注解:自己用数组实现的,没有用vector,有点笨吧!【后附 王道正规解答】
#include<cstdio>
using namespace std;
int inCount[110];//记录入度
struct relation { //边
int x, y; //左右端点
bool exsit;
}rt[110];
int main() {
int n, m;
while ( scanf("%d%d", &n, &m) != EOF) {
if (0 == n) break;
for (int i = 0; i < n; i++) {//初始化
inCount[i] = 0;
}
for (int i = 0; i < m; i++) {//输入
scanf("%d%d",&rt[i].x, &rt[i].y);
inCount[rt[i].y]++;//入度加1
rt[i].exsit = true;
}
int num = 0;
for (int i = 0; i < n; i++) {
int j;
//寻找入度为0的点
for (j = 0; j < n; j++) {
if (0 == inCount[j]) {//入度为零
num++;
inCount[j] = -1;//不然下一轮又访问到了
break;
}
}//for-j
//删除以j为起点的所有边
for (int k = 0; k < m; k++) { //上界是边数m,不是节点数n
if (rt[k].exsit == true && rt[k].x == j) {
inCount[rt[k].y]--;
rt[k].exsit = false;//删去这条边
}
}
}//for-i
if (num == n) //如果入度为0的点总数为n,即为拓扑排序
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
【转自:王道机试指南】
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
vector<int> edge[501]; //邻接链表【下标为结点, 其中所装为其指向的点】
queue<int> Q; //保存入度为0的结点
int main() {
int inDegree[501];//统计每个结点的入度
int n, m;
while (scanf("%d%d", &n, &m) != EOF) {
if (n == 0 && 0 == m) break;
//初始化
for (int i = 0; i < n; i++) {
inDegree[i] = 0;
edge[i].clear(); //清空邻接表
}
while (m--) {
int a, b;
scanf("%d%d", &a, &b);
inDegree[b]++; //入度加1
edge[a].push_back(b); //a->b
}
while (Q.empty() == false) Q.pop();//清队列
//核心步骤开始
for (int i = 0; i < n; i++) {//入度为0的结点入队列
if (0 == inDegree[i])
Q.push(i);
}
int cnt = 0; //记录入度为0的结点数
while (Q.empty() == false) {//遍历队列
int nowP = Q.front();
Q.pop();
cnt++;
for (int i = 0; i < edge[nowP].size(); i++) {
//遍历新出队列结点的邻接表
inDegree[edge[nowP][i]]--;
if (inDegree[edge[nowP][i]] == 0)//入度为0则入队列
Q.push(edge[nowP][i]);
}
}//while
if (cnt == n) puts("YES");
else puts("NO");
}//while
return 0;
}//main