題目大意:輸入兩個整數n和m,n表示字母表中前n個字母 A,B,C...., m表示下面要給出m組字母之間的大小關係。
輸出有3種可能:1.經過x次比較後,得出有序的字母序列:......;
2.經過x次比較後,發現矛盾,例如又有A<B,又有B<A,故矛盾;
3.經過m次比較之後,仍然不能確定這n個字母的準確大小關係;
需要注意的地方:輸入一組字母關係就處理一組,一旦發現n個字母已經有序,就可以不對以後的輸入處理了,就算後面輸入的字母關係可能產生矛盾,也不用管它。
/** 這題本來是在分類題拓撲排序裡面找的,在網上和書上看了半天拓撲排序的演算法,沒看太懂。 再搜別人的代碼都是很長很長的,也看不太懂, 我的思路:每輸入一組比較關係,就用Floyd演算法更新一次鄰接矩陣,檢驗有沒有環,有環則矛盾,沒有環 就繼續看是否已經有序,直到最後輸入完畢,既不矛盾也不能確定有序,那麼就是第三種情況無法確定。 我判斷是否有序的方法是:n個節點的出度分別為0,1,2...n-1,則說明有序。**/#include <stdio.h>#include <string.h>int n, m;char a[27][27], res, sort[27], out_deg[28];int function(char s1, char s2){ int i, j, k; a[s1-'A'][s2-'A'] = 1; //Floyd演算法,更新鄰接矩陣 for (k=0; k<n; k++) for (i=0; i<n; i++) for (j=0; j<n; j++) if (a[i][k] && a[k][j]) a[i][j] = 1; for (i=0; i<n; i++)//測試是否有環,有環則矛盾 { if (a[i][i]) return 2;//矛盾,返回2 } return 0;}int Test_sort()//測試是否已經為有序{ int i, j; memset(sort, 0, sizeof(sort)); memset(out_deg, 0, sizeof(out_deg)); //出度分別為0,1,2,...,n-1,則說明為有序 for (i=0; i<n; i++) { for (j=0; j<n; j++) { if (a[i][j]) out_deg[i]++; } if (sort[n-1-out_deg[i]] == 0) sort[n-1-out_deg[i]] = i+'A'; else return 0;//暫時還不能確定大小順序,返回0 } sort[n] = '/0'; return 1;//返回1表示已經確定有序}int main(){ int i, step; char s[6]; while (scanf("%d %d", &n, &m) && (n+m)) { memset(a, 0, sizeof(a)); res = step = 0; for (i=1; i<=m; i++) { scanf("%s", s); if (!res) { res = function(s[0], s[2]); if (res) step = i; if (!res) { res = Test_sort(); if (res) step = i; } } } if (res == 1) printf("Sorted sequence determined after %d relations: %s./n", step, sort); else if (res == 2) printf("Inconsistency found after %d relations./n", step); else if (res == 0) printf("Sorted sequence cannot be determined./n"); }}