算法题 拓扑排序-01-Harry and Magical Computer

China☆狼群 提交于 2020-02-02 03:46:51

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

思路:哈利用一个魔法电脑处理N个任务,但是有M个前后关系(a,b),

意思是在b执行之前必须先执行a,即a任务在b任务前,问你是否能满足要求

处理完这N个任务。用拓扑排序来写,从图中找到一个没有前驱的顶点输出。(可以遍历,也可以用优先队列维护)。删除以这个点为起点的边。(它的指向的边删除,为了找到下个没有前驱的顶点)。重复上述,直到最后一个顶点被输出。如果还有顶点未被输出,则说明有环。

#include<vector>
#include<iostream>
#include<string>
using namespace std;
int in[1050];
int map[1050][1050];
int cnt;
int i, t;
bool toposport(int x) {
	cnt = 0;
	int k;
	for (i = 1; i <= x; i++) {//将所有顶点输出,若没能输出完则表明有环
		k = -1;
		for (t = 1; t <= x; t++) {
			if (in[t] == 0) {
				k = t;
				break;
			}
		}
		if (k == -1) {//还没能将点输出完,就找不到入度为0的边说明存在环
			return false;
		}
		for (t = 1; t <= x; t++) {
			if (map[k][t] == 1) {//将这个点和他的边删去
				in[t]--;
			}
		}
		in[k] = -1;
	}
	return true;
}
int main() {
	int n, m, a, b;
	while (scanf("%d %d", &n, &m) != EOF) {
		memset(in, 0, sizeof(in));
		memset(map, 0, sizeof(map));
		for (i = 1; i <= m; i++) {
			scanf("%d %d", &a, &b);
			if (map[b][a] == 0) {
				map[b][a] = 1;
				in[a]++;
			}
		}
		if (toposport(n)) {
			printf("YES\n");
		}
		else {
			printf("NO\n");
		}
	}
	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!