1. 程式人生 > >GYM 101173 F.Free Figurines(貪心||並查集)

GYM 101173 F.Free Figurines(貪心||並查集)

efi can 初始 typedef 多余 一個 class type pri

原題鏈接

題意
俄羅斯套娃,給出一個初始狀態和終止狀態,問至少需要多少步操作才能實現狀態轉化

貪心做法
如果完全拆掉再重裝,答案是p[i]和q[i]中不為0的值的個數。現在要求尋找最小步數,顯然要減去一些多余的步數。如果初始的一些鏈的前端是終止的某一條鏈的連續的一部分,那麽這條鏈就不用被拆開再連上,這樣每一個長度為x的鏈對答案的貢獻就是-2*(x-1),對每條鏈進行同樣的操作之後就是答案

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include
<vector> #define ll long long #define ull unsigned long long #define LOCAL using namespace std; const int maxn=1e5+10; const int inf=0x3f3f3f3f; const int mod=1e9+7; int p[maxn],q[maxn]; int n; int main(){ scanf("%d",&n); int vis[maxn]; int ans=0; for(int i=1
;i<=n;i++){ scanf("%d",&p[i]); if(p[i]) vis[p[i]]=1,ans++; } for(int i=1;i<=n;i++){ scanf("%d",&q[i]); if(q[i]) vis[q[i]]=1,ans++; } for(int i=1;i<=n;i++){ if(!vis[i]){ int x=i; while(p[x]&&q[x]&&p[x]==q[x]){ ans
-=2; x=p[x]; } } } printf("%d\n",ans); return 0; }

並查集

只能進行2個操作:
1、 把一個沒有父節點的節點作為一個 沒有父節點和子節點的節點的子節點,代價為 1;

2、把一個沒有父節點的節點的子節點去掉,代價為1;

那麽只能對free的節點進行操作,所以當ai!=bi時,要先把ai拆掉,但必須先滿足ai為free才能把i變成free,
同理把i插到bi上時也要滿足bi節點為free(即該節點沒有父節點)。

#include <iostream>
#include <cstdio>
 
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 8;
 
int a[MAXN], b[MAXN], fa;
 
int main()
{
    #ifdef LOCAL
    freopen("f.txt", "r", stdin);
    //freopen("f.out", "w", stdout);
    int T = 4;
    while(T--){
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);
 
    int n, i, ans = 0, t;
    cin >> n;
    for(i = 1; i <= n; i++){
        cin >> a[i];
    }
    for(i = 1; i <= n; i++){
        cin >> b[i];
    }
    for(i = 1; i <= n; i++){
        if(a[i] == b[i]) continue;
        if(a[i] != 0){
            ans++;
            fa = a[i];
            a[i] = 0;
            while(a[fa]){
                t = fa;
                fa = a[fa];
                a[t] = 0;
                ans++;
            }
        }
    }
    for(i = 1; i <= n; i++){
        if(a[i] == b[i]) continue;
        if(b[i] != 0){
            fa = a[b[i]];
            if(fa){
                a[b[i]] = 0;
                ans++;
            }
            else{
                continue;
            }
            while(a[fa]){
                t = fa;
                fa = a[fa];
                a[t] = 0;
                ans++;
            }
        }
    }
    for(i = 1; i <= n; i++){
        if(a[i] == b[i]) continue;
        ans++;
    }
    cout << ans << endl;
    return 0;
}

GYM 101173 F.Free Figurines(貪心||並查集)