暑假集训之专题----拓扑排序题解
第一单:
Problem A
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 26 Accepted Submission(s) : 5
Problem Description
ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that just like a big family. Every day,many "holy cows" like HH, hh, AC, ZT, lcc, BF, Qinz and so on chat on-line to exchange their ideas. When someone has questions, many warm-hearted cows like Lost will come to help. Then the one being helped will call Lost "master", and Lost will have a nice "prentice". By and by, there are many pairs of "master and prentice". But then problem occurs: there are too many masters and too many prentices, how can we know whether it is legal or not? We all know a master can have many prentices and a prentice may have a lot of masters too, it's legal. Nevertheless,some cows are not so honest, they hold illegal relationship. Take HH and 3xian for instant, HH is 3xian's master and, at the same time, 3xian is HH's master,which is quite illegal! To avoid this,please help us to judge whether their relationship is legal or not. Please note that the "master and prentice" relation is transitive. It means that if A is B's master ans B is C's master, then A is C's master.
Input
The input consists of several test cases. For each case, the first line contains two integers, N (members to be tested) and M (relationships to be tested)(2 <= N, M <= 100). Then M lines follow, each contains a pair of (x, y) which means x is y's master and y is x's prentice. The input is terminated by N = 0. TO MAKE IT SIMPLE, we give every one a number (0, 1, 2,..., N-1). We use their numbers instead of their names.
Output
For each test case, print in one line the judgement of the messy relationship. If it is legal, output "YES", otherwise "NO".
Sample Input
3 2 0 1 1 2 2 2 0 1 1 0 0 0
Sample Output
YES
NO
裸裸的拓扑排序,只需要判断是否成环即可.......
代码:
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 const int maxn=105;
5 int map[maxn][maxn];
6 int indegree[maxn];
7 int n,m;
8 int main()
9 {
10 int x,y;
11 while(scanf("%d%d",&n,&m)!=EOF&&n+m!=0)
12 {
13 memset(map,0,sizeof(map));
14 memset(indegree,0,sizeof(indegree));
15 while(m--)
16 {
17 scanf("%d%d",&x,&y);
18 x++;
19 y++;
20 if(!map[x][y])
21 {
22 map[x][y]=1;
23 indegree[y]++;
24 }
25 }
26 int j;
27 bool flag=1;
28 for(int i=1;i<=n;i++)
29 {
30 for(j=1;j<=n;j++)
31 {
32 if(indegree[j]==0)
33 {
34 indegree[j]--;
35 for(int k=1;k<=n;k++)
36 {
37 if(map[j][k])
38 indegree[k]--;
39 }
40 break ;
41 }
42 }
43 if(j>n){
44 flag=0;
45 break;
46 }
47 }
48 printf(flag==0?"NOn":"YESn");
49 }
50 return 0;
51 }
Problem A
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 25 Accepted Submission(s) : 8
Problem Description
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
Input
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
Output
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。 其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input
4 3 1 2 2 3 4 3
Sample Output
1 2 4 3
基础题
代码:
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #define maxn 505
5 bool map[maxn][maxn];
6 int indegree[maxn],tp[maxn],n,m;
7 void tuopu_sort()
8 {
9 memset(tp,0,sizeof(tp)); //拓扑排序数组清空
10 int i,j,k=0,ll;
11 for(i=1;i<=n;i++)
12 {
13 for(j=1;j<=n;j++)
14 {
15 /*每次取出入读位0的数*/
16 if(indegree[j]==0)
17 {
18 indegree[j]=-1; //让他等于-1;表示舍弃掉这个数
19 tp[k++]=j; //放到拓扑序列中
20 /*进行一次循环,去掉所有这个数指向的数的一个度*/
21 for(ll=1;ll<=n;ll++)
22 {
23 if(map[j][ll]) //j-->LL 表示成为map[j][ll]
24 {
25 indegree[ll]--; //减少一个
26 }
27 }
28 break; // 终止,然后进行下次的查找
29 }
30 }
31 if(j>n)
32 {
33 //这表示构成了一个环
34 return ; //之间结束即可,但是在其他的题中,不能这样...
35 }
36 }
37 }
38 int main()
39 {
40 int i=0,fx,ty;// fx--->from x to y
41 while(scanf("%d%d",&n,&m)!=EOF)
42 {
43 memset(map,0,sizeof(map));
44 memset(indegree,0,sizeof(indegree));
45 for(i=0;i<m;i++)
46 {
47 scanf("%d%d",&fx,&ty);
48 if(!map[fx][ty]) //防止数据重复
49 {
50 map[fx][ty]=true;
51 indegree[ty]++; //入度加一
52 }
53 }
54 tuopu_sort();
55 for(i=0;i<n-1;i++)
56 {
57 printf("%d ",tp[i]);
58 }
59 printf("%dn",tp[i]);
60 }
61 return 0;
62 }
Problem B
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 17 Accepted Submission(s) : 1
Problem Description
Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards. The workers will compare their rewards ,and some one may have demands of the distributing of rewards ,just like a's reward should more than b's.Dandelion's unclue wants to fulfill all the demands, of course ,he wants to use the least money.Every work's reward will be at least 888 , because it's a lucky number.
Input
One line with two integers n and m ,stands for the number of works and the number of demands .(n<=10000,m<=20000) then m lines ,each line contains two integers a and b ,stands for a's reward should be more than b's.
Output
For every case ,print the least money dandelion 's uncle needs to distribute .If it's impossible to fulfill all the works' demands ,print -1.
Sample Input
2 1 1 2 2 2 1 2 2 1
Sample Output
1777 -1
用邻接表取代邻接矩阵(或者用STL取代之)
代码:
1 /*@coder 龚细军*/
2 #include<cstdio>
3 #include<cstring>
4 #include<cstdlib>
5 #include<queue>
6 #include<vector> //动态的二维数组
7 #include<iostream>
8 using namespace std;
9 const int maxn=10002;
10 int n,m;
11 int cnt[maxn],outd[maxn];
12 vector< vector<int> >map(maxn);
13 void tp_sort(int tol)
14 {
15 int i;
16 queue<int>st;
17 for(i=1;i<=n;i++)
18 {
19 if(!outd[i])
20 {
21 outd[i]--;
22 st.push(i);
23 break;
24 }
25 }
26 //环如何消除
27 while(!st.empty())
28 {
29 int temp=st.front();
30 vector<int>::iterator it;
31 for(it=map[temp].begin();it!=map[temp].end();it++)
32 {
33 outd[*it]--;
34 if(cnt[*it]<=cnt[temp])
35 cnt[*it]=cnt[temp]+1;
36 }
37 st.pop();
38 for(i=1;i<=n;i++)
39 {
40 if(!outd[i])
41 {
42 outd[i]--;
43 st.push(i);
44 break;
45 }
46 }
47 }
48 for(i=1;i<=n;i++)
49 {
50 if(outd[i]!=-1)
51 {
52 puts("-1");
53 return ;
54 }
55 }
56 int ans=0;
57 for(i=1;i<=n;i++)
58 {
59 ans+=cnt[i];
60 }
61 if(ans)
62 printf("%dn",n*888+ans);
63 else
64 puts("-1");
65 }
66 int main()
67 {
68 int a,b,i;
69 while(scanf("%d%d",&n,&m)!=EOF)
70 {
71 for(i=1;i<=n;i++) map[i].clear();
72 memset(outd,0,sizeof(outd));
73 memset(cnt,0,sizeof(cnt));
74 i=1;
75 while(m--)
76 {
77 scanf("%d%d",&a,&b);
78 map[b].push_back(a);
79 outd[a]++; /*out++*/
80 }
81 tp_sort(i);
82 }
83 return 0;
84 }
- Go语言归并排序算法实现
- grep无法查找shell传过来的变量?先注意一下文本格式吧!
- 深入浅出 Retrofit,这么牛逼的框架你们还不来看看?
- nwui —— 又一个go语言图形界面解决方案
- Golang 通用连接池
- 解决JS操作Cookies出现的乱码问题,修复WordPress评论乱码
- 分享一个WordPress外链跳转教程,兼容知更鸟暗箱下载和文章索引
- 让WordPress RSS/Feed订阅数据延迟发布,附RSS技巧集锦
- Linux系统防CC攻击自动拉黑IP增强版Shell脚本
- 利用artDialog给网站添加一个能显示搜索来路和关键词的欢迎框
- 解决启用wp super cache缓存后,页面追加多个斜杠仍然可以访问的隐患
- WordPress集成底部滚动推荐条,让好文章不再被埋没
- go语言base64加密解密的方法
- WordPress酷炫CSS3读者墙,排名按年度、本月、本周划分的小方法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法