拓扑排序topological sort (bfs思想)

# include<iostream>
# include<queue>
# include<cstring>
using namespace std;
const int maxn=50;
typedef struct node{
	int adj;      //顶点之间的关系 
}node;
typedef struct graph{
	int vertex[maxn];
   node vertexs[maxn][maxn];//邻接矩阵 
    int vertexnum;
    int edgenum;
}graph;
int indegree[maxn];
queue<int> q;   
vector<int> ss;   //存放拓扑排序的序列
bool vis[maxn];
int find(graph g,int i)  //寻找对应顶点的索引 
{
	for(int j=0;j<g.vertexnum;j++)
	    if(g.vertex[j]==i)
	      return j;
	return -1;
}
void init(graph &g)   //初始化图 
{
	cin>>g.vertexnum>>g.edgenum;
	for(int i=0;i<g.vertexnum;i++)
	  cin>>g.vertex[i];
	for(int i=0;i<g.vertexnum;i++)
	  for(int j=0;j<g.vertexnum;j++)
	      g.vertexs[i][j].adj=0;
	for(int i=0;i<g.edgenum;i++)
	{
		int u,v;
		cin>>u>>v;
	    int index_u=find(g,u);
		int index_v=find(g,v);
		if(index_u==-1||index_v==-1)
		  {
		  	  cout<<"不存在该节点"<<endl;
		  	 continue;
			} 
		g.vertexs[index_u][index_v].adj=1;   	
	  }
}
int finddegree(graph g,int indegree[])  //计算每个顶点的入度,并存放在indegree数组的相应位置 
{
	int sum;
	for(int j=0;j<g.vertexnum;j++)
	{
	 sum=0;
	  for(int i=0;i<g.vertexnum;i++)
	  {
	  	sum+=g.vertexs[i][j].adj;
	    }
	   indegree[j]=sum;
     }
} 
bool topological(graph g)   //可以设置标记数组vis,也可不设 
{
	for(int i=0;i<g.vertexnum;i++)   //将顶点入度为0的顶点入队列 
	 {
	 	if(indegree[i]==0)   
	 	   q.push(i);  
	  } 
	  int cnt=0;
	while(!q.empty())
	{
		int i=q.front();
		q.pop();    //居然忘了出队列,服了自己了。 
		vis[i]=true;
		ss.push_back(g.vertex[i]);   //保存图的顶点
		cnt++;   //计数加一
		for(int j=0;j<g.vertexnum;j++)
		{  
		   if(g.vertexs[i][j].adj)   //如果有从i->j的边
		   { 
		       indegree[j]--;  //将顶点j的入度减一
		       if(!indegree[j]&&!vis[j])   //如果入度为0
		       {
              	vis[j]=true;
		       	  q.push(j);     //加入队列
			   }
			   }	
		}
	}
	if(cnt<g.vertexnum)    
	  return false;
    else return true;
}
int main()
{
	graph g;
	init(g);
	/*for(int i=0;i<g.vertexnum;i++)
	 {
	 	for(int j=0;j<g.vertexnum;j++)
	 	   cout<<g.vertexs[i][j].adj<<" ";
	 	cout<<endl;
	  } 
	  */
	  //cout<<endl;
	  finddegree(g,indegree);    
	//for(int i=0;i<g.vertexnum;i++)
	  // cout<<indegree[i]<<" ";
//	  memset(vis,0,sizeof(vis));
	if(topological(g))
	  {
	  	  for(vector<int> ::iterator in=ss.begin();in!=ss.end();++in)
	  	     cout<<*in<<" ";
	  	cout<<endl;
	  }
	else {
	  	cout<<"存在回路"<<endl;
	  }

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值