hdu4857(反向拓扑排序)

来源:互联网 发布:淘宝闪电退货卖家拒收 编辑:程序博客网 时间:2024/05/16 00:39
折腾了一下午,一开始以为从1....n分别找出反向路径进行输出,然后就是正确的姿势了,提交了一两把,发现是错的,比如下面的case:
  4 3  
  4 2
  2 1
  3 1

  正解应该是4 2 3 1, 而我的是3 4 2 1,后面的2的位置明显靠后,然后看了想了一下符合反向拓扑排序的规律,所以建边的时候反着建就可以了。

  当然输出也要是逆向的,这个时候借助一下栈就可以了。

  

#include "stdio.h"#include "string.h"#include "math.h"#include <string>#include <queue>#include <stack>#include <vector>#include <map>#include <algorithm>#include <iostream>using namespace std;#define MAX 100005#define max(a,b) a > b ? a : b#define min(a,b) a < b ? a : b#define abs(a)  a < 0 ? a : (-a)#define Mem(a,b) memset(a,b,sizeof(a))int Mod = 1000000007;double pi = acos(-1.0);double eps = 1e-6;typedef struct{int f,t,next;}Edge;Edge edge[MAX];int head[MAX];int indree[MAX];int kNum;void addEdge(int f, int t){edge[kNum].f = f;edge[kNum].t = t;edge[kNum].next = head[f];head[f] = kNum ++;}int T, n, m;void solve(){Mem(head, -1);Mem(indree, 0);int u,v;kNum = 0;priority_queue<int, vector<int>, less<int>> q; //小到大stack<int> ans;for(int i = 0; i < m; i ++){scanf("%d %d",&u, &v);addEdge(v,u);indree[u] ++;}for(int i = 1; i <= n; i ++){if( indree[i] == 0 )q.push(i);}while( !q.empty() ){int t = q.top();ans.push(t);q.pop();for(int k = head[t]; k != -1; k = edge[k].next){indree[edge[k].t] --;if( indree[edge[k].t] == 0 )q.push(edge[k].t);}}bool flag = true;while( !ans.empty() ){if( flag ){flag = false;printf("%d",ans.top());}elseprintf(" %d",ans.top());ans.pop();}printf("\n");}int main(){//freopen("d:\\test.txt", "r", stdin);while(cin>>T){while( T-- ){cin>>n>>m;solve();}}return 0;}

0 0