POJ2367 拓扑排序 裸题 板子题
http://poj.org/problem?id=2367
队列版
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <sstream> 7 #include <algorithm> 8 #include <string> 9 #include <queue> 10 #include <map> 11 #include <vector> 12 using namespace std; 13 const int maxn = 1e3+50; 14 const int maxm = 1e4+10; 15 const int inf = 0x3f3f3f3f; 16 const int mod = 998244353; 17 const double epx = 1e-6; 18 typedef long long ll; 19 const ll INF = 1e18; 20 const double pi = acos(-1.0); 21 vector<int> g[maxn]; 22 int rudu[maxn],order[maxn],vis[maxn]; 23 int n,m,cnt; 24 void toposort() 25 { 26 priority_queue<int,vector<int>,greater<int> > q; 27 for(int i=1;i<=n;i++) 28 if(rudu[i]==0) 29 q.push(i),vis[i]=1; 30 while(!q.empty()) 31 { 32 int v=q.top();q.pop(); 33 order[cnt++]=v; 34 for(int i=0;i<g[v].size();i++) 35 { 36 int u=g[v][i]; 37 rudu[u]--; 38 if(rudu[u]==0) 39 q.push(u),vis[u]=1; 40 } 41 } 42 } 43 int main() 44 { 45 cin>>n; 46 memset(rudu,0,sizeof(rudu)); 47 memset(order,0,sizeof(order)); 48 memset(vis,0,sizeof(vis)); 49 for(int i=1;i<=n;i++) 50 { 51 int u,v; 52 do{ 53 cin>>v; 54 if(v!=0) 55 g[i].push_back(v),rudu[v]++; 56 }while(v!=0); 57 } 58 cnt=0;toposort(); 59 if(cnt==n) 60 for(int i=0;i<n;i++) 61 { 62 if(i==n-1) 63 cout<<order[i]<<endl; 64 else 65 cout<<order[i]<<" "; 66 } 67 //else 68 //cout<<"no"<<endl; 69 }
dfs版
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <sstream> 7 #include <algorithm> 8 #include <string> 9 #include <queue> 10 #include <map> 11 #include <vector> 12 using namespace std; 13 const int maxn = 1e3+50; 14 const int maxm = 1e4+10; 15 const int inf = 0x3f3f3f3f; 16 const int mod = 998244353; 17 const double epx = 1e-6; 18 typedef long long ll; 19 const ll INF = 1e18; 20 const double pi = acos(-1.0); 21 int g[maxn][maxn]; 22 int c[maxn],n,m; 23 int topo[maxn],t; 24 bool dfs(int u) //思想是 一直搜找到当前没有出度的点 存到数组里 逆序操作 25 { 26 c[u]=-1; //c数组 0表示没有访问过 -1表示还在栈中尚未返回 1表示已经访问完 27 for(int v=1;v<=n;v++) 28 { 29 if(g[u][v]) 30 { 31 if(c[v]<0) 32 return false; //当前节点已经在栈中了 说明有环 返回false 33 else if(!c[v]&&!dfs(v)) 34 return false; //若子节点搜索过程中遇到环 向前返回失败 35 } 36 } 37 c[u]=1;topo[t--]=u; //遍历完之后存到数组里 38 return true; 39 } 40 bool toposort() 41 { 42 t=n; 43 memset(c,0,sizeof(c)); 44 for(int u=1;u<=n;u++) 45 if(!c[u]&&!dfs(u)) 46 return false; //如果当前节点没有被访问过 进行dfs 若返回false 说明环 不能拓扑排序 47 return true; 48 } 49 int main() 50 { 51 cin>>n; 52 memset(g,0,sizeof(g)); 53 for(int i=1;i<=n;i++) 54 { 55 int u; 56 while(1) 57 { 58 cin>>u; 59 if(u==0) 60 break; 61 g[i][u]=1; 62 } 63 } 64 if(toposort()) 65 { 66 for(int i=1;i<=n-1;i++) 67 cout<<topo[i]<<" "; 68 cout<<topo[n]<<endl; 69 } 70 }