2024杭電多校第8場

Aderose_yr發表於2024-08-16

8

1006 cats的最小生成樹 (hdu7522

對於總共 \(m\) 條邊而言,有效操作次數不會超過 \(k = \lfloor m/(n - 1)\rfloor\) 次,每次對 \(n\) 個點做最小生成樹,考慮用 \(k\) 個並查集維護每次操作過程中圖的連通性,整體空間複雜度 \(O(m)\). 連邊操作時,二分查詢左右端點不連通的最早時刻,極端情況下時間複雜度 \(m\cdot log(m)\). 最後對每個並查集檢查連通性,若第 \(i\) 次操作時圖已經無法連通,則大於該操作次數的邊都不會被加入生成樹,輸出-1.

    int lev = m / (n - 1); // 即題解中的k
    if(lev == 0) {
        for(int i = 1; i <= m; i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            printf("-1 ");
        }
        printf("\n");
        return; // 按我的程式碼不特判就會re()
    }
    for(int i = 1; i <= lev; i++) {
        for(int j = 0; j <= n + 1; j++) {
            f[i].push_back(j);
        }
    }
    for(int i = 1; i <= m; i++) {
        int x, y, l = 1, r = lev;
        scanf("%d%d", &x, &y);
        ans[i] = lev + 1;
        if(find(lev, x) == find(lev, y)) continue;
        while(l <= r) {
            int mid = (l + r) / 2;
            if(find(mid, x) != find(mid, y)) {
                ans[i] = mid;
                r = mid - 1;
            } else l = mid + 1;
        }
        f[ans[i]][find(ans[i], x)] = find(ans[i], y);
    }
    int flag = lev + 1;
    for(int i = 1; i <= lev; i++) {
        int cnt = 0;
        for(int j = 1; j <= n; j++) {
            if(f[i][j] == j) cnt++;
        }
        if(cnt > 1) {
            flag = i;
            break;
        }
    }
    for(int i = 1; i <= m; i++) {
        if(ans[i] >= flag) printf("-1 ");
        else printf("%d ", ans[i]);
    }

1012 cats 的電腦中毒 (hdu7528

非常好題目,正解就是貪心的題還能想假也是離譜()將兩個字串不同字元的位置數量看作它們的“距離”,題意即轉化為:求一個字串 \(x\),其與三個給定字串距離的最小值最大。嗯,看上去有點像二分或者dp,但經過我和wyq的嘗逝,這兩種思路都不對。

對於給定字串 \(a,b,c\) 的第 \(i\) 位,若 \(a[i] = b[i] = c[i]\)\(x[i] \neq a[i]\) 顯然是最優的,統計三個字串相等的情況次數 \(s\);若 \(a[i] = b[i] \neq c[i]\),可暫時令 \(x[i] = c[i]\). 統計每個字串與另外兩者不等的次數,記作 \(cnt_a,cnt_b,cnt_c\). 此時 \(d_{ax} = s + cnt_b + cnt_c,\space d_{bx} = s + cnt_a + cnt_c, \space d_{cx} = s + cnt_a + cnt_b\),假設 \(cnt_a \leq cnt_b\leq cnt_c\),對於當前最小距離 \(d_{cx}\) 而言,適當調整 \(a[i] = b[i] \neq c[i]\) 情況下的取值、即令部分 \(x[i] = a[i],\space min(d_{ax} - k, d_{bx} - k, d_{cx} + k) = d_{cx} + k\) 顯然更佳;該調整操作最多對一個字串進行,若調整兩個字串的取值,使這兩個字串距離不變、另一字串距離減小,答案不會更優。調整應當使 \(d_{cx}'\) 與較小的 \(d_{bx}'\) 儘可能接近,即有最終答案 \(d = s + cnt_a + (cnt_b + cnt_c) / 2\).

相關文章