拓扑排序按我的理解就是寻找入度为0的结点(输出或存入数组),将其所有的邻接边都删除。遍历整个图,直至删除完所有结点
删除操作就是看将对应的邻接边的入度减一
基本思想如下:
我用邻接矩阵存储图压缩空间,加快时间
vector<int> Graph[510];//邻接表 int visite[510];//标记结点是否被访问 int cnt[510];//记录每个顶点的入度 int find_indegree(int n)//查找未被访问结点中入度为0的结点 { int i; for(i=1;i<=n;i++) { if(visite[i]==0&&cnt[i]==0) { visite[i]=1; return i; } } return -1; } void TopSort(int n) { int i,j; for(i=0;i<n;i++)//n次循环用来输出n个结点 { int v=find_indegree(n); if(v==-1) cout<<"error"<<endl; else { if(i<n-1)//格式化输出 cout<<v<<" "; else cout<<v<<endl; for(j=0;j<Graph[v].size();j++)//查找当前结点的所有邻接边使其入度减一 cnt[Graph[v][j]]--; } } }
对应基础练习:http://acm.hdu.edu.cn/showproblem.php?pid=1285
答案:
#include<iostream> #include<cstring> #include<vector> using namespace std; vector<int> Graph[510];//邻接表 int visite[510];//标记结点是否被访问 int cnt[510];//记录每个顶点的入度 int find_indegree(int n)//查找未被访问结点中入度为0的结点 { int i; for(i=1;i<=n;i++) { if(visite[i]==0&&cnt[i]==0) { visite[i]=1; return i; } } return -1; } void TopSort(int n) { int i,j; for(i=0;i<n;i++)//n次循环用来输出n个结点 { int v=find_indegree(n); if(v==-1) cout<<"error"<<endl; else { if(i<n-1)//格式化输出 cout<<v<<" "; else cout<<v<<endl; for(j=0;j<Graph[v].size();j++)//查找当前结点的所有邻接边使其入度减一 cnt[Graph[v][j]]--; } } } int main() { int n,m; while(cin>>n>>m) { memset(visite,0,sizeof(visite)); memset(cnt,0,sizeof(cnt)); for(int i=0;i<m;i++) { int a,b; cin>>a>>b; Graph[a].push_back(b);//记录b的入度为a; cnt[b]++;//b的入度加一 } TopSort(n); for(int i=1;i<=n;i++) Graph[i].clear();//清空邻接矩阵 } return 0; }
文章来源: 拓扑排序