【洛谷P1347】排序
阿新 • • 發佈:2018-11-08
題目大意:給定 N 個變數和 M 個變數之間的偏序關係,問能否求出這 N 個變數之間的一個全序。若能,輸出最少利用多少條已知資訊即可求的結果,且輸出該全序;若無解,輸出到第幾條已知資訊可以判定無解;若讀到最後一條資訊也無法判斷,輸出無法判斷。
題解:偏序關係自然對應著一個有向圖,每一個已知資訊等價為給這個有向圖加一條邊,若能夠得到全序,則證明拓撲排序過程中能夠找出一條長度為 N 的鏈,若無解,則是在拓撲排序過程中存在自環,否則就是無法判斷。
程式碼如下
#include <bits/stdc++.h> using namespace std; const int maxn=30; vector<int> G[maxn]; char ops[10]; int n,m,idx,indeg[maxn],tmp[maxn],stk[maxn],top,d[maxn];//d[i]為以 i 結尾的最長路徑 bool circle,certain; inline void add_edge(int from,int to){G[from].push_back(to),++indeg[to];} void topo_sort(int now){ queue<int> q;int dep=1;//dep為當前DAG上的最長路徑的長度 for(int i=1;i<=n;i++)d[i]=0; for(int i=1;i<=n;i++){ tmp[i]=indeg[i]; if(!tmp[i])q.push(i),d[i]=1; } top=0; while(q.size()){ int u=q.front();q.pop(); stk[++top]=u; for(int i=0;i<G[u].size();i++){ int v=G[u][i];--tmp[v]; if(!tmp[v])q.push(v); d[v]=max(d[v],d[u]+1); dep=max(dep,d[v]); } } if(top^n)circle=1,idx=now; else if(dep==n)certain=1,idx=now; } void solve(){ for(int i=1;i<=m;i++){ scanf("%s",ops+1); if(circle||certain)break; int from=ops[1]-'A'+1,to=ops[3]-'A'+1; add_edge(from,to); topo_sort(i); } if(certain){ printf("Sorted sequence determined after %d relations: ",idx); for(int i=1;i<=n;i++)printf("%c",stk[i]+'A'-1); printf(".\n"); } else if(circle)printf("Inconsistency found after %d relations.\n",idx); else printf("Sorted sequence cannot be determined.\n"); } int main(){ scanf("%d%d",&n,&m); solve(); return 0; }