拓扑排序

来源:互联网 发布:js获取div滚动条位置 编辑:程序博客网 时间:2024/05/29 07:26


/*
拓扑排序: 对事件优先级的排序




  */
#include<iostream>


#include<vector>
#define Max 10000
using namespace std;


vector<int > map[Max];


int used[Max];
int index[Max];


void init(){
memset(used,0,sizeof(used));
memset(index,0,sizeof(index));
for(int i(0); i<Max ; i++){
map[i].clear();
}
}


int find_zero (int n ){
for(int i(1); i<=n ;i++){
//如果该点没有被扩充,并且入度为0则返回值i
if( index[i]==0 && !used[i] )
return i;
}


//执行这条语句就表明没有符合条件的点存在,可能存在环,
return -1;
}


void cut( int k ){

//将相连的节点的入度减一,表示没有了这条边
for(int i(0); i< map[k].size() ; i++){
index[map[k][i]]--;
}
//一种习惯,彻底将边删除
map[k].clear();
}




//主函数,三步走


/*
1,查找入度为0 的节点 k
2.将 k 可以达到的节点入度减一,之后也可以将边全部删除
3.标记该点已经被扩充过 



  */
void topology( int n){
int save[Max];
int p(0);
for(int i(1); i<=n; i++){
int k= find_zero( n );   //1---------

//用k来判断是否没有找到要求的点,一种编程习惯
if( k==-1)break;
cut(k);                  //2--------
used[k]=1; //3--------
save[p++]= k;
}


for(int j(0); j<p-1; j++){
cout<<save[j]<<' ';
}
cout<<save[j]<<endl;
}


int main(){
int n,m;


while(cin>>n>>m){


init();
int a, b;

//构建拓扑图,记录各点的入度
for(int i(1); i<=m; i++){
cin>>a>>b;
map[a].push_back(b);
index[b]++;
}


topology(n );
}


return 0;
}
原创粉丝点击