poj 3687 拓扑排序

题意:求一个拓扑排序,使其weight是递增的,当有多个序列存在是,要求首先使1号的weight最小,然后是2号....

解题思路:

对于一个有向无环图,若按质量轻的往质量大的建边,那么当有多个入度为0的点存在时,不能确定将哪个放在前面能使其最终序列最优,但反过来思考,

对于出度为0的所有点,其中编号最大的让其排到最后面,那么结果一定是最优的。

#include<iostream>

#include<cstdio>

#include<cstring>

#define Maxn 402

#define Maxm 40010

using namespace std;

int graphic[Maxn][Maxn],indegree[Maxn],n,m,ans[Maxn],label;

int Topsort()

{

    int i,j,k,num=0;

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

    {

        for(j=n;j>=1;j--)

        {

            if(indegree[j]==0)

            {

                indegree[j]--;

                ans[j]=label--;

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

                    if(graphic[j][k])

                        indegree[k]--;

                num++;

                break;

            }

        }

    }

    if(num<n)

        return 0;

    return 1;

}

int main()

{

    int t,i,j,a,b;

    scanf("%d",&t);

    while(t--)

    {

        memset(indegree,0,sizeof(indegree));

        memset(graphic,0,sizeof(graphic));

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

        for(i=0;i<m;i++)

        {

            scanf("%d%d",&a,&b);

            if(!graphic[b][a])

                indegree[a]++,graphic[b][a]=1;

        }

        label=n;

        if(Topsort())

        {

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

                printf("%d ",ans[i]);

            printf("%d\n",ans[i]);

        }

        else

            printf("-1\n");

    }

    return 0;

}
View Code

 

你可能感兴趣的:(poj)