1. 程式人生 > >UVA 10305 Ordering Tasks(拓撲排序的隊列解法)

UVA 10305 Ordering Tasks(拓撲排序的隊列解法)

題目 space while 一行 class == 整數 cstring 關系

題目鏈接:

https://vjudge.net/problem/UVA-10305#author=goodlife2017

題目描述

John有n個任務,但是有些任務需要在做完另外一些任務後才能做。

輸入

輸入有多組數據,每組數據第一行有兩個整數1 <= n <= 100mn是任務個數(標記為1n),m兩個任務直接關系的數量。在此之後,有m行,每行有2個整數ij,代表任務i必須在任務j之前完成。用n = m = 0結束整個輸入。

輸出

每一個數據對應一行n個整數,代表任務完成的順序。

樣例輸入

	5 4
	1 2
	2 3
	1 3
	1 5
	0 0

樣例輸出

	1 4 2 5 3
 1
/* 2 問題 給出變量的個數n和m個二元組,輸出任意一個從小到大的排序 3 解題思路 由題中所給的m個二元組可以得到每個點的入度,創建一個隊列,先將入度為0的點加入隊列, 4 然後依次出隊,出隊過程中將以該點為起點的那條邊的終點的入度減去1,如果該點的入度變為0,就將該點也加入隊列, 5 直到隊列為空。 如果隊列為空後,出隊的點的個數等於總個數,則說明有拓撲序列,否則說明圖內有環,夠不成拓撲序列。 6 */ 7 #include<iostream> 8 #include<cstdio> 9 #include<cstring> 10 #include<vector> 11
#include<queue> 12 using namespace std; 13 14 const int maxn=110; 15 16 vector<int> g[maxn];//表示以g[i]為起點的邊,比如表示1——2和1——3這兩條邊,g[1]中第一個元素為2,第二個元素為3 17 int rd[maxn]; 18 int topo[maxn]; 19 20 bool toposort(int n); 21 22 int main() 23 { 24 int m,n,i,u,v,j,flag; 25 while(scanf("%d%d
",&n,&m), n + m != 0){ 26 for(i=1;i<=m;i++){ 27 scanf("%d%d",&u,&v); 28 flag=0; 29 for(j=0;j<g[u].size();j++) 30 if(g[u][j] == v) 31 { 32 flag=1; 33 break; 34 } 35 if(!flag) g[u].push_back(v); 36 } 37 38 if(toposort(n)){ 39 for(i=0;i<n-1;i++) 40 printf("%d ",topo[i]); 41 printf("%d\n",topo[n-1]); 42 } 43 44 for(i=0;i<=n;i++) 45 g[i].clear(); 46 } 47 return 0; 48 } 49 50 bool toposort(int n) 51 { 52 int i,j; 53 memset(rd,0,sizeof(rd)); 54 for(i=1;i<=n;i++){ 55 for(j=0;j<g[i].size();j++){ 56 rd[ g[i][j] ]++; 57 } 58 } 59 60 int t=0; 61 queue<int> q; 62 for(i=1;i<=n;i++) 63 if(rd[i]==0){ 64 q.push(i); 65 } 66 67 int x; 68 while(!q.empty()){ 69 x=q.front(); 70 q.pop(); 71 topo[t++]=x; 72 for(i=0;i<g[x].size();i++){ 73 j=g[x][i]; 74 rd[ j ]--; 75 76 if(rd[j]==0) 77 q.push(j); 78 } 79 } 80 81 if(t==n) return 1; 82 return 0; 83 }

UVA 10305 Ordering Tasks(拓撲排序的隊列解法)