AcWing 1921. 重新排列奶牛
阿新 • • 發佈:2022-05-28
題意
可以選擇任意頭奶牛,將他們進行迴圈移位,給定移位前的順序和移位後的順序,請計算奶牛們完成重新排列,共需多少組迴圈移位,最長的一組迴圈移位的長度是多少。
示例:
移位前:5 1 4 2 3
移位後:2 5 3 1 4
如上例中,將 5,1,2 號奶牛分在一組進行迴圈移位,移動過後,5 號奶牛移動至位置 2,1 號奶牛移動至位置 4,2 號奶牛移動至位置 1;將 4,3 號奶牛分在另一組進行迴圈移位,移動過後,4 號奶牛位於位置 5,3 號奶牛位於位置 3;最終完成重新排列。
資料範圍
\(1 \le N \le 100\)
\(1 \le A(i), B(i) \le N\)
題解
注意環的長度為1的情況,不僅需要排除自環,還要排除單個的點,注意ans1和ans2的計數。
程式碼
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 110; int a[N], b[N]; int e[N], ne[N], h[N], idx; bool st[N]; int n; void add(int a, int b){ e[idx] = b, ne[idx] = h[a], h[a] = idx ++; } int bfs(int x){ int res = 0; queue<int> q; q.push(x); while(q.size()){ auto t = q.front(); q.pop(); //cout << t << ' '; res ++; for(int i = h[t]; i != -1; i = ne[i]){ int j = e[i]; if(st[j]) continue; q.push(j); st[j] = true; } } //cout << '\n'; return res; } int main() { scanf("%d", &n); for(int i = 0; i < n; i ++) scanf("%d", &a[i]); for(int i = 0; i < n; i ++) scanf("%d", &b[i]); memset(h, -1, sizeof h); for(int i = 0; i < n; i ++) { if(a[i] != b[i]) add(b[i], a[i]); } int ans1 = 0, ans2 = -1; for(int i = 0; i < n; i ++){ if(!st[a[i]]){ st[a[i]] = true; int t = bfs(a[i]); if(t > 1) ans2 = max(ans2, t), ans1 ++; } } printf("%d %d\n", ans1, ans2); return 0; }