4 3 1 2 2 3 4 3
1 2 4 3
————————————————————————————————————————————————
拓扑排序的模板题,广度优先
码1:
#include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> #include<functional> #define vi vector<int> #define M 500+10 using namespace std; vi g[M]; int degree[M],c[M]; int n,m; bool toposort() { int count=0; priority_queue<int,vector<int>,greater<int> > pq; for(int u=1;u<=n;++u){ if(!degree[u]) pq.push(u); //入度为0的入队 } while(!pq.empty()){ int u=pq.top();pq.pop(); c[count++]=u; for(int i=0;i<g[u].size();++i){ //与它相邻节点 int v=g[u][i]; degree[v]--; //入度减一 if(!degree[v]) pq.push(v); //入度为0的入队 } } if(count<n) return false; //说明有环, return true; } int main() { while(scanf("%d %d",&n,&m)!=EOF){ int u,v; for(int i=1;i<=n;++i){ g[i].clear(); } memset(degree,0,sizeof degree); while(m--){ scanf("%d %d",&u,&v); g[u].push_back(v); //构建邻接表 degree[v]++; } if(toposort()){ for(int i=0;i<n;++i){ printf("%d",c[i]); if(i!=n-1) printf(" "); } } printf("\n"); } return 0; }
码2:
#include<iostream> #include<cstring> #include<vector> #include<cstdio> #define M 500+10 #define vi vector<int> using namespace std; int n,m,degree[M],count,topo[M]; vi g[M]; int main() { while(scanf("%d %d",&n,&m)!=EOF){ count=0,memset(degree,0,sizeof degree); for(int i=1;i<=n;++i) g[i].clear(); int u,v; while(m--){ scanf("%d %d",&u,&v); g[u].push_back(v); degree[v]++; } for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ if(degree[j]==0){ degree[j]=-1; topo[count++]=j; for(int k=0;k<g[j].size();++k){ v=g[j][k]; degree[v]--; } break; } } } if(count==n){ for(int i=0;i<n;++i){ printf("%d",topo[i]); if(i!=n-1) printf(" "); } printf("\n"); } } return 0; }
13231
HDU 1285——确定比赛名次(拓扑排序入门),布布扣,bubuko.com
原文:http://blog.csdn.net/u014141559/article/details/38414881