拓扑排序--九度1448

题目: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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值