前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >暑假集训之专题----拓扑排序题解

暑假集训之专题----拓扑排序题解

作者头像
Gxjun
发布2018-03-22 14:10:40
6180
发布2018-03-22 14:10:40
举报
文章被收录于专栏:ml

第一单:

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

裸裸的拓扑排序,只需要判断是否成环即可.......

 代码:

代码语言:javascript
复制
 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?"NO\n":"YES\n");
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

基础题

代码:

代码语言:javascript
复制
 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("%d\n",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取代之)

代码:

代码语言:javascript
复制
 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("%d\n",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 }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-07-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Problem A
  • Problem A
  • Problem B
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档