poj 2367

题意  :给你一些顶点,先是输入总顶点数,第几行就代表以该数字为起点,这一行里面的值则代表该行的起点会指向哪些点,当顶点为0时,则表示该行的输入结束,输入另一行的元素,然后输出拓扑排序。   拓扑排序是指 在一个有向图中,找出入度为0的那个顶点,然后输出该顶点,去掉该顶点指向其他顶点的边,然后对应的顶点的入度要减1.  然后重新在图中找入度为0的顶点,然后输出该顶点,去掉该顶点指向其他顶点的边,然后对应的顶点的入度要减1。一直重复,直到所有顶点输出

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const  int M = 100;  //设定一个最大值
int n; //确定有几个顶点
vector<int> map[M];//定义一个动态数组
int in[M];//定义输入的数组,用来存储输入了哪些数据
int out[M];//定义输出的数在组
void toposort()
{
int i;
queue<int>Q;  //定义一个队列
for (i = 1; i <= n; i++)
{
if (!in[i])//判断当前顶底是否已经存在于输入数组中
{
Q.push(i);//如果没就把它入栈
}
}
int count = 0;//把计数变量设定为0
while (!Q.empty())//判断队列是否已经空了
{
int u = Q.front();//如果没有就把队首元素记录下来然后输出
Q.pop();
out[++count] = u;//把队首元素的值存入输出数组中,等下用来输出
for ( i = 0; i <map[u].size(); i++)
{
int m = map[u][i];//得到某个顶点
if (--in[m] == 0)//判断某个顶点去除目前这个顶点指向它的路径之后是否如入度为0
{
Q.push(m);//如果为0就入栈
}
}
}
}
int main()
{
int i;//数组下标
while (scanf("%d",&n)==1&&n)//输入顶点数
{
for ( i = 1; i<=n; i++)//用来控制以哪个起点作为起点
{
map[i].clear();//先对map数组进行清空
in[i] = 0;//先对输入数组的每个值赋0
int m;//输入与该起点指向的顶点
while(1)
{
scanf("%d", &m);
if (m == 0)//如果该元素等于0,表示该顶点指向的顶点已经全部列举完了
{
break;
}
map[i].push_back(m);//把该元素输入到对应的起点的空间
in[m]++;对本节的的入度进行++,因为又有一个顶点指向该顶点了
}
}
toposort(); 
for (int i = 1; i <=n; i++)//输出拓扑排序
{
if (i < n)
{
//cout << out[i]<<" ";
printf( "%d ", out[i] );
}
else
{
//cout << out[i]<<" ";
printf( "%d\n", out[i] );
}
}

}
return  0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值