藍書(演算法競賽進階指南)刷題記錄——POJ1094 Sorting It All Out(floyd)
阿新 • • 發佈:2018-11-10
題目:POJ1094.
題目大意:給定n組不等關係,格式為x<y.現在要求輸出最早能夠確定唯一順序或產生矛盾的位置,或輸出沒有這樣一個位置,若有唯一順序要輸出順序.
注意這道題的輸出格式.
這道題一看想到了差分約束,仔細一想用floyd跑差分約束,然後發現好像確實可做.
我們用設f[i][j]為true表示i<j,那麼我們可以將所有關係轉化,然後就可以跑一遍Floyd,接下來若有一對x,y滿足f[x][y]=f[y][x]=true,就說明矛盾,否則說明不矛盾.
要求出第幾對之後矛盾,我們可以二分求解,或者也可以暴力列舉在第幾對之後.
若不矛盾,我們要確定唯一順序的話,我們可以發現若有唯一順序的話,那麼肯定滿足一對x,y不存在f[x][y]=f[y][x]=false的情況.
求出唯一順序可以使用暴力列舉每一個點,也可以直接使用拓撲排序求解.
至於求解在第幾對之後,二分一下就好,當然也可以暴力列舉.
我這道題一開始以為它是要先判斷所有邊是否有矛盾或有唯一順序,但是題目是要邊讀入邊判.
程式碼如下:
//#include<bits/stdc++.h> #include<iostream> using namespace std; #define Abigail inline void typedef long long LL; const int N=26,M=N*N; struct side{ int x,y; }e[M+9]; int n,m; int flag,ans,pre[N+9]; int f[N+9][N+9]; void floyd(int mid){ if (mid>m) mid=m; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) f[i][j]=0; for (int i=1;i<=mid;i++) f[e[i].x][e[i].y]=1; for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) f[i][j]|=f[i][k]&f[k][j]; } bool check_con(int mid){ if (mid>m) mid=m; floyd(mid); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i^j&&f[i][j]&f[j][i]) return true; return false; } bool check_order(int mid){ if (mid>m) mid=m; floyd(mid); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i^j&&!(f[i][j]^f[j][i])) return false; return true; } char rc(){ char c=getchar(); while (c<'A'||c>'Z') c=getchar(); return c; } Abigail into(){ char c1,c2; for (int i=1;i<=m;i++){ c1=rc();c2=rc(); e[i].x=c1-'A'+1;e[i].y=c2-'A'+1; } } Abigail work(){ flag=2; for (int i=1;i<=m;i++){ if (check_con(i)) flag=0; if (check_order(i)) flag=1; ans=i; if (flag^2) break; } } Abigail outo(){ switch (flag){ case 0:printf("Inconsistency found after %d relations.\n",ans); break; case 1:printf("Sorted sequence determined after %d relations: ",ans); floyd(ans); for (int i=1;i<=n;i++) pre[i]=0; //查了一個下午錯發現自己沒有初始化pre為0... for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (f[i][j]&&i^j) pre[j]++; for (int i=0;i<n;i++) for (int j=1;j<=n;j++) if (pre[j]==i) putchar(j-1+'A'); putchar('.');putchar('\n'); break; case 2:printf("Sorted sequence cannot be determined.\n"); break; } } int main(){ while (~scanf("%d%d",&n,&m)&&n){ into(); work(); outo(); } return 0; }