poj2367 拓扑排序入门

怼烎@ 2022-08-09 16:37 247阅读 0赞

先来一道拓扑排序的裸题吧!!

首先要知道拓扑排序的概念,拓扑排序就是,先找到入度为0的点,删去,同时把它的所有出度删去,再找新的入度为0的点,删去的点的顺序就是拓扑序

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. using namespace std;
  5. int in[10001];//入度
  6. int v[1001][101];//标记
  7. int b[10001];//存输出
  8. int main()
  9. {
  10. int i,j,k,n,m,l,t;
  11. while(~scanf("%d",&n))
  12. {
  13. memset(v,0,sizeof(v));
  14. memset(in,0,sizeof(in));
  15. for(i=1;i<=n;i++)
  16. {
  17. while(scanf("%d",&t)&&t)
  18. {
  19. v[i][t]=1;
  20. in[t]++;
  21. }
  22. }
  23. int tmp;
  24. for(i=1;i<=n;i++)
  25. {
  26. for(j=1;j<=n;j++)
  27. {
  28. if(in[j]==0)//找入度为0的点
  29. {
  30. k=j;
  31. break;
  32. }
  33. }
  34. in[j]=-1;
  35. b[i]=k;
  36. for(j=1;j<=n;j++)
  37. {
  38. if(v[k][j]==1)
  39. {
  40. v[k][j]=0;
  41. in[j]--;
  42. }
  43. }
  44. }
  45. for(i=1;i<=n;i++)
  46. {
  47. printf("%d ",b[i]);
  48. }
  49. puts("");
  50. }
  51. return 0;
  52. }

用队列的话:

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<queue>
  4. using namespace std;
  5. int in[19991],v[1001][1001],b[10001],m,n,cnt;
  6. queue<int>qq;
  7. void tuopu()
  8. {
  9. while(!qq.empty())
  10. {
  11. int st1=qq.front();
  12. qq.pop();
  13. b[cnt++]=st1;
  14. //in[st1]=-1;
  15. for(int j=1;j<=n;j++)
  16. {
  17. if(v[st1][j])
  18. {
  19. v[st1][j]=0;
  20. in[j]--;
  21. }
  22. }
  23. for(int i=1;i<=n;i++)
  24. {
  25. if(in[i]==0)
  26. {
  27. qq.push(i);
  28. in[i]=-1;
  29. }
  30. }
  31. }
  32. }
  33. int main()
  34. {
  35. int i,j,k,t,l;
  36. while(~scanf("%d",&n))
  37. {
  38. cnt=0;
  39. memset(in,0,sizeof(in));
  40. memset(v,0,sizeof(v));
  41. for(i=1;i<=n;i++)
  42. {
  43. while(scanf("%d",&t)&&t)
  44. {
  45. in[t]++;
  46. v[i][t]=1;
  47. }
  48. }
  49. for(i=1;i<=n;i++)
  50. {
  51. if(in[i]==0)
  52. {
  53. qq.push(i);
  54. in[i]=-1;
  55. }
  56. }
  57. tuopu();
  58. for(i=0;i<cnt;i++)
  59. printf("%d ",b[i]);
  60. printf("\n");
  61. }
  62. return 0;
  63. }

空间优化

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<string.h>
  4. #include<cstring>
  5. #include<string>
  6. #include<stack>
  7. #include<set>
  8. #include<algorithm>
  9. #include<cmath>
  10. #include<vector>
  11. #include<map>
  12. #define LOCAL
  13. #define ll long long
  14. #define lll unsigned long long
  15. #define MAX 1000009
  16. #define eps 1e-8
  17. #define INF 0x7fffffff
  18. #define mod 1000000007
  19. using namespace std;
  20. /*
  21. 题意:
  22. 想法:
  23. */
  24. int n,m;
  25. int head[MAX];
  26. int p[MAX];
  27. int next[MAX];
  28. int edgecnt;
  29. int Count[MAX];
  30. int ans[MAX];
  31. int k;
  32. void addedge(int u,int v)
  33. {
  34. ++edgecnt;
  35. p[edgecnt] = v;
  36. next[edgecnt] = head[u];
  37. head[u] = edgecnt;
  38. }
  39. void init()
  40. {
  41. memset(Count,0,sizeof(Count));
  42. memset(head,0,sizeof(head));
  43. memset(next,0,sizeof(next));
  44. }
  45. void topsort()
  46. {
  47. k = 0;
  48. int sum = 0;
  49. stack<int>Q;
  50. int top = -1;
  51. for(int i = 1; i<=n; i++)
  52. {
  53. if(Count[i]==0)
  54. {
  55. Q.push(i);
  56. }
  57. }
  58. while(!Q.empty())
  59. {
  60. int u = Q.top();
  61. Q.pop();
  62. ans[k++] = u;
  63. for(int i = head[u]; i; i = next[i])
  64. {
  65. int v = p[i];
  66. Count[v]--;
  67. if(Count[v]==0)
  68. {
  69. Q.push(v);
  70. }
  71. }
  72. }
  73. }
  74. int main()
  75. {
  76. //freopen("date.in","r",stdin);
  77. int T;
  78. while(~scanf("%d",&n))
  79. {
  80. init();
  81. for(int i = 1; i<=n; i++)
  82. {
  83. int u,v;
  84. while(1)
  85. {
  86. u = i;
  87. scanf("%d",&v);
  88. if(v==0)break;
  89. else
  90. {
  91. Count[v]++;
  92. addedge(u,v);
  93. }
  94. }
  95. }
  96. topsort();
  97. for(int i = 0; i<k; i++)
  98. {
  99. if(i)
  100. printf(" ");
  101. printf("%d",ans[i]);
  102. }
  103. puts("");
  104. }
  105. return 0;
  106. }

发表评论

表情:
评论列表 (有 0 条评论,247人围观)

还没有评论,来说两句吧...

相关阅读

    相关 poj2367 拓扑排序入门

    先来一道拓扑排序的裸题吧!! 首先要知道拓扑排序的概念,拓扑排序就是,先找到入度为0的点,删去,同时把它的所有出度删去,再找新的入度为0的点,删去的点的顺序就是拓扑序

    相关 poj 1094 拓扑排序

    悲剧,这题错得好惨,首先这题题意就没仔细看清,误读题意。 读懂题意后又悲剧了,当不确定时还要判断是否有回路。 判断回路时又用了错误算法,思考不认真,当然知道可以用Floyd

    相关 拓扑排序

     一个较大的工程往往被划分成许多子工程,我们把这些子工程称作活动(activity)。在整个工程中,有些子工程(活动)必须在其它有关子工程完成之后才能开始,也就是说,一个子工程