POJ2367Genealogical tree拓扑排序&前向星

题意困扰我好久==

家族谱,儿子不能在父亲的前面输出

样例解释:总共有那个人, 第i 行的输入代表i的后代,输入0停止,

辈分从高到底输出

拓扑排序代码:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define N 110
int edge[N][N], n;
int find()
{
	int i, j, y;
	for(i = 1; i <= n; i++)
	{
		if(!edge[i][0])
		{
			y = i;
			break;
		}
	}
	for(j = 1; j<= n; j++)
	{
		if(edge[y][j])
		{
			edge[j][0]--;
		}
	}
	edge[y][0]--;
	return y;
}
int main()
{
	cin >> n;
	memset(edge, 0, sizeof(edge));
	for(int i = 1; i<= n; i++)
	{
		int x;
		while(scanf("%d", &x) && x != 0)
		{
			edge[i][x] = 1;
			edge[x][0]++;
		}
	}
	cout << find();
	for(int i = 1; i < n; i++)
	{
		cout << " " << find();
	}
	return 0;
}

前向星代码:

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#define MAX 1005
using namespace std;
///前向星存储结构,下标从0开始
struct GraphQX
{
	vector<int> to;///当前边指向的点
	vector<int>pre;///当前边的前一条边
	vector<int>info;///当前点指向的最后一条边
	int zroENode;///有意义的0边的起始点
	GraphQX(int eSize = 0, int nSize = 0)
	{
		to.resize(eSize);
		info.resize(nSize);
		pre.resize(eSize);
		zroENode = - 1;
	}
	void expan(int i)
	{
		if (info.size() < i + 1)
		{
			info.resize(i + 1);
		}
	}
	//增加a, b边;
	void addEdge(int a, int b)
	{
		expan(a);
		expan(b);
		to.push_back(b);
		pre.push_back(info[a]);
		info[a] = to.size() - 1;

		if (info[a] == 0) //0边上的起始点,其他0边上的起始点不是真正的起点,遇到0边可以直接退出
		{
			zroENode = a;
		}
	}
	//删除最后一条边
	void deletLastEdge()
	{
		for (int i = 0; i < info.size(); i++)
		{
			if (info[i] == to.size() - 1)
			{
				info[i] = pre.back();
				break;
			}
		}

		pre.pop_back();
		to.pop_back();
	}
	//清空
	void clear()
	{
		info.clear();
		pre.clear();
		to.clear();
		zroENode = -1;
	}
};

GraphQX qx;
int Num;
int du[MAX];
vector<int>ans;
void bfs()
{
	queue<int>q;
	for (int i = 0; i < Num; i++)
	{
		if (du[i] == 0)
		{
			q.push(i);
		}
	}
	while (!q.empty())
	{
		int u = q.front(), v;
		q.pop();
		ans.push_back(u + 1);
		if (u  < qx.info.size()) //判断越界,边对应的点相对小的情况就会越界
		{
			int e = qx.info[u];
			while (e)
			{
				v = qx.to[e];
				du[v]--;
				if (du[v] == 0)
				{
					q.push(v);
				}
				e = qx.pre[e];
			}
			if (u == qx.zroENode && qx.zroENode != -1)
			{
				v = qx.to[0];
				du[v]--;

				if (du[v] == 0)
				{
					q.push(v);
				}
			}
		}
	}
	for (int i = 0; i < ans.size() - 1; i++)
	{
		cout << ans[i] << " ";
	}
	cout << ans.back() << endl;
}

int main()
{
	cin >> Num;
	int a;
	ans.clear();
	qx.clear();
	memset(du, 0, sizeof(du));
	for (int i = 0; i < Num; i++)
	{
		while (cin >> a, a != 0)
		{
			qx.addEdge(i, a - 1);
			du[a - 1]++;
		}
	}
	bfs();
}



posted @ 2014-09-25 20:50  豪气干云  阅读(200)  评论(0编辑  收藏  举报