POJ 3687 拓扑排序

来源:互联网 发布:apache cxf 教程 编辑:程序博客网 时间:2024/05/21 09:05

反向建图!!反向遍历!!





#include<stdio.h>

#include<iostream>
#include<string.h>
using namespace std;
int rudu[205];
int mp[205][205];
int vis[205];
int ans[205];
int n,m;
int main()
{
    int t;
    int x,y,flag;
    cin>>t;
    while(t--)
    {
        memset(rudu,0,sizeof(rudu));
        memset(mp,0,sizeof(mp));
        memset(vis,0,sizeof(vis));
        memset(ans,0,sizeof(ans));
       cin>>n>>m;
        flag=0;
        for(int i=0;i<m;i++)
        {
            cin>>x>>y;
            if(mp[y][x]==0)
                rudu[x]++;
            mp[y][x]=1;
            if(x==y)
                flag=1;
        }
        if(flag==1)
        {
               cout<<"-1"<<endl;
               continue;
        }
        int cnt=n;
        while(1)
        {
            int k=-1;
            for(int i=n;i>=1;i--)
            {
                if(rudu[i]==0&&vis[i]==0)
                {
                    k=i;
                    vis[i]=1;
                    break;
                }
            }
            if(k==-1) break;
            ans[k]=cnt--;
                for(int j=1;j<=n;j++)
                {
                    if(mp[k][j]==1) rudu[j]--;
                }
           }
           if(cnt!=n)
           {
                cout<<"-1"<<endl;
                continue;
           }
           for(int i=1;i<=n;i++)
           {
               if(i!=1) cout<<" ";
               cout<<n-ans[i];
           }
           cout<<endl;
       //}
    }
    return 0;

}





快速的:http://www.cnblogs.com/Tree-dream/p/5748312.html

利用优先队列来做

#include <stdio.h>
#include <string.h>
#include <queue>
#define maxn 210


using namespace std;


int digree [ maxn ];        //这个就是入度值。
int judge [ maxn ][ maxn ];     //这个是用来判断有没有重边的。
int location [ maxn ];
int m,n;


priority_queue<int >s;     //这个是默认的最大优先队列。


int topsort()
{
    int num = n;
    for( int i = 1 ; i <= n ; i++ )
        if(!digree[ i ]) s.push( i );
    if( s.empty() )  return 0;    //如果没有入度为0的,则说明构成了一个环。
    while( !s.empty() )
    {
        int tmp =s.top();
        s.pop();
        location [ tmp ] = num--;
        for( int i = 1 ; i <= n ; i++ )
        {
            if( judge[ i ][ tmp ] )
            {
                judge[ i ][ tmp ] = 0;
                digree[ i ] --;
                if( !digree[ i ] ) s.push( i );
            }
        }
    }
    if( num != 0 ) return 0;    //如果这里Num 不能等于0,那么说明最少还有两个是无法确定的。
    return 1;
}




int main()
{
    int t,a,b;
    scanf("%d",&t);
    while( t -- )
    {
        memset( digree , 0 , sizeof( digree ) );
        memset( judge , 0 , sizeof( judge ) );
        memset( location , 0 , sizeof( location ) );
        scanf("%d%d",&n,&m);
        for( int i = 1 ; i <= m ; i ++ )
        {
            scanf("%d%d",&a,&b);
            if(judge[ a ][ b ] > 0) continue;   //判重。
            judge[ a ][ b ] = 1;
            digree [ a ] ++;
        }
        a = topsort();
        if( a ) {
            int i = 1;
            for( ; i < n ; printf("%d ",location[ i++ ]) );
            printf("%d\n",location[ i ]);
        }


        else printf("-1\n");
    }
    return 0;
}

原创粉丝点击