码迷,mamicode.com
首页 > 编程语言 > 详细

HDU 3342 Legal or Not (拓扑排序)

时间:2016-05-07 11:13:05      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

Legal or Not

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6742 Accepted Submission(s): 3180


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


题解:这个题的大致意思是说:一个A向B请教,B是A的师父,A是B的徒弟,一个人可以有多个徒弟,也可以有多个师父,但不能是同一个人的师父和徒弟(不合法)或者在整个大圈子里也不可以同是为一个人的师父并且也是其徒弟(例如A是B的师父,A也是B的徒弟、或者大圈子里A是B的师父,B是C的师父

A是C的徒弟)(均不合法)

主要的意思就是让判断是否存在环(如果可以进行拓扑排序,则表示无环,否则有环)


代码:(采用数组模拟关系)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
using namespace std;
const int maxx=105;
int map[maxx][maxx];///记录两者之间的关系
int coun[maxx];///记录入度
int n,m;
int find()
{
    int ans;  
    for(int k=0; k<n; k++)
    {
        ans=n;///每一轮都查看是否具有入度为0的点
        for(int i=0; i<n; i++)
        {
            if(coun[i]==0)
            {
                coun[i]--;
                ans=i;
                break;
            }
        }
        if(ans==n)///如果不存在入度为0 的点则有环
            return 0;
        for(int j=0; j<n; j++)
            if(map[ans][j])
                coun[j]--;///将与入度为0 的点的其他点入度均减一
    }
    return 1;
}

int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        if(n==0&&m==0)
            break;
        memset(map,0,sizeof(map));
        memset(coun,0,sizeof(coun));
        for(int i=0; i<m; i++)
        {int u,v;
            scanf("%d %d",&u,&v);
            if(!map[u][v])///有可能存在重复的关系去除
            {
                map[u][v]=1;
                coun[v]++; ///入度加一
            }
        }
        int flag=find();
        if(flag)/// 如果可以进行拓扑排序则表示无环
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}


代码2  :是采用邻接表来做的

///拓扑排序,判断是否有环(HDU 3342)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>

using namespace std;
const int maxx=505;

struct Arode
{
    int to;
    struct Arode *next;
};
 Arode *List[maxx];//邻接表
int coun[maxx];///记录入度
char output[maxx];///输出表此时用不到(不用输出排序后的顺序)
int n,m;

void Topsort()
{
    Arode *temp;
    int i;
    int top=-1;
    bool bycile=false;
    for(int i=n-1;i>=0;i--)
    {
        if(coun[i]==0)
        {
            coun[i]=top;
            top=i;
        }
    }
    int pos=0;
    for(int i=0;i<n;i++)
    {
        if(top==-1)
        {
            bycile=true;
            break;
        }
            int j=top;
            top=coun[top];
                ///pos+=sprintf(output+pos,"%d ",j+1);///输出的顺序,此时用不到
                temp=List[j];
                while(temp!=NULL)
                {
                    int k=temp->to;
                    if(--coun[k]==0)
                    {
                        coun[k]=top;
                        top=k;

                    }
                    temp=temp->next;
                }

    }
    if(bycile)
        printf("NO\n");
        else
            printf("YES\n");
}
int main()
{
  while(scanf("%d %d",&n,&m)&&(n+m))
  {
        Arode *temp;
        memset(coun,0,sizeof(coun));
        memset(output,0,sizeof(output));
        memset(List,0,sizeof(List));
        int i,j;
       int u,v;
      for(i=0;i<m;i++)
      {
          scanf("%d %d",&u,&v);
          coun[v]++;
          temp=new Arode;
          temp->to=v;
          temp->next=NULL;
          if(List[u]==NULL)
            List[u]=temp;
          else
          {
              temp->next=List[u];
              List[u]=temp;
          }
      }
      ///拓扑排序函数
      Topsort();
     ///释放邻接表所占的空间
      for(j=0;j<n;j++)
      {
          temp=List[i];
          while(temp!=NULL)
          {
              List[i]=temp->next;
              delete temp;
              temp =List[i];
          }
      }
  }

    return 0;
}



HDU 3342 Legal or Not (拓扑排序)

标签:

原文地址:http://blog.csdn.net/jingttkx/article/details/51334685

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!