toposort

来源:互联网 发布:淘宝子账号认证失败 编辑:程序博客网 时间:2024/05/22 07:40

拓扑排序,感觉就是入度的问题,比如很多人比赛,判断哪个是冠军就是入度,也就是输的场数,为0的那个人


现在有两道题,第一道,a必须排在b前面的排序问题,uva10305

这个用队列做的:

//

//  main.cpp

//  d.u10305

//

//  Created by Mr.Xue on 17/2/3.

//  Copyright © 2017 Mr.Xue. All rights reserved.

//


#include <iostream>

#include <string.h>

#include <stdio.h>

#include <queue>

using namespacestd;

int n,m,a[105][105],flag[105];

void toposort()

{

    queue<int> q;

    for(int i=1;i<=n;i++)

    {

        if(flag[i]==0)

        {

            q.push(i);

            printf("%d ",i);

        }

        

    }

    while(!q.empty())

    {

        int temp=q.front();

        q.pop();

        for(int i=1;i<=n;i++)

        {

            if(a[temp][i]!=0)

            {

                flag[i]--;

                if(flag[i]==0)

                {

                    q.push(i);

                    printf("%d ",i);

                }

            }

        }

    }

}

int main()

{

    

    while(scanf("%d %d",&n,&m))

    {

        if(n==0&&m==0)

            break;

        memset(flag,0,sizeof(flag));

        memset(a,0,sizeof(a));

        int i,j;

        while(m--)

        {

            scanf("%d %d",&i,&j);

            a[i][j]=1;

            flag[j]++;

        }

        toposort();

        printf("\n");

    }

    return0;

}

/*

5 4

1 2

2 3

1 3

1 5

0 0

*/

用for循环的,就当做bfs吧,滑稽脸

//

//  main.cpp

//  d.u10305

//

//  Created by Mr.Xue on 17/2/3.

//  Copyright © 2017 Mr.Xue. All rights reserved.

//


#include <iostream>

#include <string.h>

using namespacestd;

int main()

{

    int n,m,a[105][105],i,j,flag[105];

    while(scanf("%d %d",&n,&m))

    {

        if(n==0&&m==0)

            break;

        memset(flag,0,sizeof(flag));

        memset(a,0,sizeof(a));

        while(m--)

        {

            scanf("%d %d",&i,&j);

            a[i][j]=1;

            flag[j]++;

        }

        for(int i=1;i<=2*n;i++)

        {

            for(int j=1;j<=n;j++)

            {

                if(flag[j]==0)

                {

                    printf("%d ",j);

                    for(int k=1;k<=n;k++)

                        if(a[j][k]!=0)

                            flag[k]--;

                    flag[j]=-1;

                }

            }

        }

        printf("\n");

    }

    //cout << "Hello, World!\n";

    return0;

}


下面这道题是h2094,给出谁打败了谁,判断就没有冠军是谁

//

//  main.cpp

//  c.h2094

//

//  Created by Mr.Xue on 17/1/22.

//  Copyright © 2017 Mr.Xue. All rights reserved.

//  这道题有点小问题,只要符合没有被击败过的人的人数==1,那么就输出Yes按照这个思想写,过了- -IBut。。。明显不对呀- -IegA击败BB击败C;同时有:D击败EE击败FF击败D后者是个循环么,根本就不可能判断出A击败了DEF么,暴汗- -III,只能说题意不清吧。

//这题应该用并查集的,当所有的flag都指向同一个目标的时候,冠军就诞生了,冠军就是目标。    但是。。。用并查集写出来竟然WA

//后面的是并查集,至少懂了一个并查集的应用

#include <iostream>

#include <stdio.h>

#include <string.h>

using namespacestd;

int flag[110];

char word[110][110];

int main()

{

    int n,k;

    char str1[100],str2[100];

    while(scanf("%d",&n)&&n!=0)

    {

        int i1,i2;

        k=0;

        memset(flag,0,sizeof(flag));

        for(int j=0;j<n;j++)

        {

            scanf("%s %s",str1,str2);

           // printf("%s %s\n",str1,str2);

            for(i1=1;i1<=k;i1++)

                if(strcmp(word[i1],str1)==0)

                    break;

            //printf("%d\n",i1);

            if(i1>k)

            {

                strcpy(word[i1-1],str1);

                k++;

            }

            

            for(i2=1;i2<=k;i2++)

                if(strcmp(word[i2],str2)==0)

                    break;

            if(i2>k)

            {

                strcpy(word[i2-1],str2);

                k++;

            }

            flag[i2]=1;

        }

        int sum=0;

        for(int i=1;i<=k;i++)

            if(flag[i]==0)

                sum++;

        if(sum==1)

            printf("Yes\n");

        else

            printf("No\n");

            

    }

    return0;

}

/*

3

a b

a c

b c

 */

/*

#include <iostream>

#include <stdio.h>

#include <string.h>

using namespace std;

int flag[110];

char word[110][110];

int main()

{

    int n,k;

    char str1[100],str2[100];

    while(scanf("%d",&n)&&n!=0)

    {

        int i1,i2;

        k=0;

        for(int j=0;j<1111;j++)

            flag[j]=j;

        for(int j=0;j<n;j++)

        {

            scanf("%s %s",str1,str2);

            for(i1=1;i1<=k;i1++)

                if(strcmp(word[i1],str1)==0)

                    break;

            if(i1>k)

            {

                strcpy(word[i1-1],str1);

                k++;

            }

            

            for(i2=1;i2<=k;i2++)

                if(strcmp(word[i2],str2)==0)

                    break;

            if(i2>k)

            {

                strcpy(word[i2-1],str2);

                k++;

            }

            flag[i2]=flag[i1];

        }

        int sum=0,temp=k;

        while(temp--)

        {

           for(int j=1;j<=k;j++)

              flag[j]=flag[flag[j]];

        }

        for(int i=1;i<=k;i++)

            if(flag[i]!=flag[k+1])

                sum++;

        if(sum!=0)

            printf("No\n");

        else

            printf("Yes\n");

        

    }

    return 0;

}

 */




0 0