[傳遞閉包] P2881 [USACO07MAR]排名的牛Ranking the Cows
阿新 • • 發佈:2021-09-27
P2881 [USACO07MAR]Ranking the Cows G
傳遞閉包 + bitset 優化
題意
FJ想按照奶牛產奶的能力給她們排序。
現在已知有\(N (1 \le N \le 10^3)\) 頭奶牛。FJ通過比較,已經知道了 \(M (1 \le M \le 10^4)\) 對相對關係。
每一對關係表示為X Y
,意指X
的產奶能力強於Y
。
現在FJ想要知道,他至少還要調查多少對關係才能完成整個排序。
傳遞閉包
傳遞閉包指一個圖上的點 \(x\),是否可以到達除了點 \(x\) 外的其他點。
傳遞閉包的儲存形式類似鄰接矩陣。
傳遞閉包的實現類似 Floyd
。
for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (E[i][k] && E[k][j]) E[i][j] = 1;
具體說明可見 知乎——演算法學習筆記(57): 傳遞閉包
Code
此題暴力使用傳遞閉包會 TLE
。
要使用 bitset
優化。
具體看程式碼。
const int N = 1005; bitset<N> g[N]; int n,m; int main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) g[i][i] = 1; for(int i=1;i<=m;i++) { int u,v; cin>>u>>v; g[u][v] = 1; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) if(g[i][k]) g[i] |= g[k]; int ans = 0; for(int i=1;i<=n;i++) ans += g[i].count(); cout<<n * (n - 1) / 2 - ans + n << endl; return 0; }