HDU 3342

来源:互联网 发布:淘宝卖家退款要验证码 编辑:程序博客网 时间:2024/05/22 02:02

       这是一道拓扑排序的题目,由于题目这只要求判断是否存在拓扑序列,所以方法不会受到限制。

       要判断是否存在拓扑序列,就是要判断有向图中是否有环,我们可以从两个角度来解决问题:1)通过图的遍历,寻找是否有环;2)常规的处理拓扑排序的方法,即通过维护一个入度数组来找拓扑序列,如果处理到最后仍然有入度不为0的节点,那么便是有环图。

        如果你会拓扑排序,那么方法2就不成问题,个人认为方法1,更有价值一些。这里的深搜的标记单单不是1和0来标记一个节点访问或未访问,而是在此基础上加一个状态-1表示访问过该节点并且正在访问此节点的后代节点,而1表示访问完该节点及其后代节点,这样就可以判断图中是否有环。顺便说一下,用这种方法深搜,不但可以判断图中是否有环,还可以找一个拓扑序列(参见:《算法竞赛入门经典》(刘汝佳)P110)。

       下面分别给出代码(G++):

方法一:

#include <cstdlib>#include <iostream>#define MAX 120using namespace std;struct edge{   int to;   int next;    }; edge array[MAX*MAX];int head[MAX],vis[MAX];int n;bool dfs(int x){    int i;     vis[x]=-1;    for(i=head[x];i!=-1;i=array[i].next)    {                if(vis[array[i].to]==-1) return false;        if(vis[array[i].to]==0&&!dfs(array[i].to)) return false;            }     vis[x]=1;    return true;}int main(int argc, char *argv[]){    int m,a,b,i,c;    while(cin>>n>>m&&n+m!=0)    {        memset(head,-1,sizeof(head));         memset(vis,0,sizeof(vis));          c=0;                         for(i=0;i<m;i++)        {            cin>>a>>b;            array[c].to=b;            array[c].next=head[a];            head[a]=c;               c++;                 }         for(i=0;i<n;i++)        {            if(0==vis[i]&&!dfs(i))            {                                cout<<"NO"<<endl;                break;            }                }        if(i==n) cout<<"YES"<<endl;                               }    system("PAUSE");    return EXIT_SUCCESS;}


方法2:

#include <cstdlib>#include <iostream>#define MAX 120using namespace std;struct edge{    int to;    int next;   };int indegree[MAX],head[MAX],queue[MAX];edge array[MAX*MAX];int main(int argc, char *argv[]){    int n,m,i,j,a,b,c,ans;    while(cin>>n>>m&&n+m!=0)    {         memset(indegree,0,sizeof(indegree));         memset(head,-1,sizeof(head));         c=ans=0;                           for(i=0;i<m;i++)         {             cin>>a>>b;             array[c].to=b;             array[c].next=head[a];             head[a]=c++;             indegree[b]++;         }         for(i=0;i<n;i++)         {             if(indegree[i]==0) queue[ans++]=i;         }         for(i=0;i<ans;i++)         {             for(j=head[queue[i]];j!=-1;j=array[j].next)              {                  indegree[array[j].to]--;                  if(indegree[array[j].to]==0) queue[ans++]=array[j].to;             }                      }         if(ans==n) cout<<"YES"<<endl;         else cout<<"NO"<<endl;    }    system("PAUSE");    return EXIT_SUCCESS;}


题目:

Legal or Not

                                                                            Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


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 20 11 22 20 11 00 0
 

Sample Output
YESNO


0 0
原创粉丝点击