题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285
题目给出一些点对之间的先后顺序,要求给出一个字典序最小的拓扑排列。对于拓扑排序的问题,我们有DFS和BFS都能够解决,但是问题是DFS只能处理上一层结点和下一层结点相对于根节点之间的距离,也就是说深度就是他们之间的先后顺序,对于同一层的,是没有先后顺序的,但是BFS可以处理同一层之间的先后关系,所以我们考虑用BFS进行遍历,并且将原始BFS求拓扑排序中的队列变成优先队列。这样我们就能在每一层中优先选择字典序小的结点先输出。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define mp(a,b) make_pair((a),(b)) 17 #define P pair<int,int> 18 #define dbg(args) cout<<#args<<":"<<args<<endl; 19 #define inf 0x3f3f3f3f 20 const int maxn=505; 21 int n,m,t; 22 inline int read(){ 23 int ans=0,w=1; 24 char ch=getchar(); 25 while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} 26 while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); 27 return ans*w; 28 } 29 struct node{ 30 int u,v; 31 }p[maxn]; 32 int e; 33 int vis[maxn][maxn],head[maxn],nxt[maxn],in[maxn],num[maxn];//in表示入度 34 void init() 35 { 36 e=0; 37 mem(vis,0);mem(head,-1);mem(nxt,-1);mem(in,0); 38 mem(num,0);//排名信息置零 39 } 40 void addedge(int u,int v) 41 { 42 p[e].u=u; 43 p[e].v=v; 44 nxt[e]=head[u]; 45 head[u]=e++; 46 } 47 void topsort() 48 { 49 priority_queue<int,vector<int> ,greater<int> > q;//最小堆 50 f(i,1,n) 51 { 52 if(in[i]==0)q.push(i);//将入度为零的点按照字典序排在优先队列中 53 } 54 int t=0,id;//用BFS对付topsort时从队列中出来的点的顺序实际上就是topsort完成之后应该有的排序 55 while(!q.empty()) 56 { 57 num[t++]=id=q.top(); 58 q.pop(); 59 for(int i=head[id];~i;i=nxt[i])//扫描从这一点出发的所有的边 60 { 61 in[p[i].v]--;//所到的点的入度减一 62 if(in[p[i].v]==0)q.push(p[i].v);//将入度为0的点归入优先队列 63 } 64 } 65 //将所有的点都扫描过之后,由于一定存在拓扑序,所以直接输出结果 66 pf("%d",num[0]); 67 f(i,1,n-1)pf(" %d",num[i]); 68 pf("\n"); 69 } 70 int main() 71 { 72 //freopen("input.txt","r",stdin); 73 //freopen("output.txt","w",stdout); 74 std::ios::sync_with_stdio(false); 75 while(scanf("%d%d",&n,&m)!=EOF) 76 { 77 init(); 78 int a,b; 79 f(i,1,m) 80 { 81 a=read(),b=read(); 82 if(!vis[a][b])//保证两条边之间的只有一条有向边,否则出入度就会发生变化,导致错误 83 { 84 addedge(a,b); 85 vis[a][b]=1; 86 in[b]++; 87 } 88 } 89 topsort(); 90 } 91 92 }
来源:https://www.cnblogs.com/randy-lo/p/12577618.html