poj2367 拓扑排序入门

先来一道拓扑排序的裸题吧!!

首先要知道拓扑排序的概念,拓扑排序就是,先找到入度为0的点,删去,同时把它的所有出度删去,再找新的入度为0的点,删去的点的顺序就是拓扑序

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int in[10001];//入度
int v[1001][101];//标记
int b[10001];//存输出
int main()
{
	int i,j,k,n,m,l,t;
	while(~scanf("%d",&n))
	{
		memset(v,0,sizeof(v));
		memset(in,0,sizeof(in));
		for(i=1;i<=n;i++)
		{
			while(scanf("%d",&t)&&t)
			{
				v[i][t]=1;
				in[t]++;
			}
		}
		int tmp;
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(in[j]==0)//找入度为0的点
				{
					k=j;
					break;
				}
			}
			in[j]=-1;
			b[i]=k;
			for(j=1;j<=n;j++)
			{
				if(v[k][j]==1)
				{
					v[k][j]=0;
					in[j]--;
				}
			}
		}
		for(i=1;i<=n;i++)
		{
			printf("%d ",b[i]);
		}
		puts("");
	}
	return 0;
}

用队列的话:

#include<stdio.h>
#include<algorithm>
#include<queue> 
using namespace std;
int in[19991],v[1001][1001],b[10001],m,n,cnt;
queue<int>qq;
void tuopu()
{
	while(!qq.empty())
	{
		int st1=qq.front();		
		qq.pop();
		b[cnt++]=st1;	
		//in[st1]=-1;
		for(int j=1;j<=n;j++)
		{
			if(v[st1][j])
			{
				v[st1][j]=0;
				in[j]--;
			}
		}
	
		for(int i=1;i<=n;i++)
		{
			if(in[i]==0)
			{
				qq.push(i);	
				in[i]=-1;
			}
		}
	}
}
int main()
{
	int i,j,k,t,l;
	while(~scanf("%d",&n))
	{
		cnt=0;
		memset(in,0,sizeof(in));
		memset(v,0,sizeof(v));
		for(i=1;i<=n;i++)
		{
			while(scanf("%d",&t)&&t)
			{			
					in[t]++;
					v[i][t]=1;
			}
		}
		
		for(i=1;i<=n;i++)
		{
			if(in[i]==0)
			{
				qq.push(i);
				in[i]=-1;
			} 
		} 
		tuopu();
		for(i=0;i<cnt;i++)
			printf("%d ",b[i]); 
		printf("\n");
	}
	
	return 0;
}

空间优化

#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>

#define LOCAL
#define ll long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007

using namespace std;
/*

题意:

想法:

*/
int n,m;
int head[MAX];
int p[MAX];
int next[MAX];
int edgecnt;
int Count[MAX];
int ans[MAX];
int k;

void addedge(int u,int v)
{
    ++edgecnt;
    p[edgecnt] = v;
    next[edgecnt] = head[u];
    head[u] = edgecnt;
}
void init()
{
    memset(Count,0,sizeof(Count));
    memset(head,0,sizeof(head));
    memset(next,0,sizeof(next));
}
void topsort()
{
    k = 0;
    int sum = 0;
    stack<int>Q;
    int top =  -1;
    for(int i = 1; i<=n; i++)
    {
        if(Count[i]==0)
        {
            Q.push(i);
        }
    }
    while(!Q.empty())
    {
        int u = Q.top();
        Q.pop();
        ans[k++] = u;
        for(int i = head[u]; i; i = next[i])
        {
            int v = p[i];
            Count[v]--;
            if(Count[v]==0)
            {
                Q.push(v);
            }
        }
    }
}
int main()
{
    //freopen("date.in","r",stdin);
    int T;
    while(~scanf("%d",&n))
    {
        init();
        for(int i = 1; i<=n; i++)
        {
            int u,v;
            while(1)
            {
                u = i;
                scanf("%d",&v);
                if(v==0)break;
                else
                {
                    Count[v]++;
                    addedge(u,v);
                }
            }
        }
        topsort();
        for(int i = 0; i<k; i++)
        {
            if(i)
                printf(" ");
            printf("%d",ans[i]);
        }
        puts("");
    }
    return 0;
}

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/yzllz001/article/details/49558517
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞