主题链接:http://pat.zju.edu.cn/contests/ds/6-06
假定一个project项目由一组子任务构成,子任务之间有的能够并行运行。有的必须在完毕了其他一些子任务后才干运行。
“任务调度”包含一组子任务、以及每一个子任务能够运行所依赖的子任务集。
比方完毕一个专业的全部课程学习和毕业设计能够看成一个本科生要完毕的一项project,各门课程能够看成是子任务。
有些课程能够同一时候开设,比方英语和C程序设计,它们没有必须先修哪门的约束;有些课程则不能够同一时候开设,由于它们有先后的依赖关系。比方C程序设计和数据结构两门课,必须先学习前者。
可是须要注意的是,对一组子任务,并非随意的任务调度都是一个可行的方案。
比方方案中存在“子任务A依赖于子任务B,子任务B依赖于子任务C,子任务C又依赖于子任务A”,那么这三个任务哪个都不能先运行,这就是一个不可行的方案。你如今的工作是敲代码判定不论什么一个给定的任务调度是否可行。
输入格式说明:
输入说明:输入第1行给出子任务数N(<=100)。子任务按1~N编号。随后N行。每行给出一个子任务的依赖集合:首先给出依赖集合中的子任务数K,随后给出K个子任务编号,整数之间都用空格分隔。
输出格式说明:
假设方案可行。则输出1,否则输出0。
例子输入与输出:
序号 | 输入 | 输出 |
1 |
4 0 1 1 1 1 2 2 3 |
1 |
2 |
12 0 0 2 1 2 0 1 4 1 5 2 3 6 1 3 2 7 8 1 7 1 10 1 7 |
1 |
3 |
4 1 4 2 1 4 1 2 1 3 |
0 |
PS:
用拓扑排序,如有节点不能被删除则有环!
代码例如以下:
#include <cstdio> #include <cstring> #define MAXN 517 int G[MAXN][MAXN];//路径 int in_degree[MAXN];//入度 int ans[MAXN]; int n, m, x, y; int i, j; int flag = 0; void toposort() { flag = 0; for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { if(G[i][j]) { in_degree[j]++; } } } for(i = 1; i <= n; i++)//从最小的開始寻找, { //这样保证了有多个答案时序号小的先输出 int k = 1; while(in_degree[k] != 0)//寻找入度为零的点 { k++; if(k > n) { flag = 1; break; } } ans[i] = k; in_degree[k] = -1; //更新为-1,后边检測不受影响,相当于删除节点 for(int j = 1; j <= n; j++) { if(G[k][j]) in_degree[j]--;//相关联的入度减1 } } } void init() { memset(in_degree,0,sizeof(in_degree)); memset(ans,0,sizeof(ans)); memset(G,0,sizeof(G)); } int main() { while(~scanf("%d",&n)) { init(); for(i = 1; i <= n; i++) { scanf("%d",&m); for(int j = 0; j < m; j++) { scanf("%d",&y); G[i][y] = 1; } } toposort(); if(flag) { printf("0 "); } else printf("1 "); } return 0; }
版权声明:本文博客原创文章,博客,未经同意,不得转载。