zoukankan      html  css  js  c++  java
  • 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();
    }
    



    www.cnblogs.com/tenlee
  • 相关阅读:
    [BZOJ 1698] 荷叶池塘
    [BZOJ 3132] 上帝造题的七分钟
    [JLOI2011] 飞行路线
    [Codeforces Round49F] Session in BSU
    [BZOJ 3036] 绿豆蛙的归宿
    CRC-16校验原理
    ubuntu下mysql的安装与配置
    【OpenCV】边缘检测:Sobel、拉普拉斯算子
    我对sobel算子的理解
    梯度算子(普通的+Robert + sobel + Laplace)
  • 原文地址:https://www.cnblogs.com/tenlee/p/4420122.html
Copyright © 2011-2022 走看看