CF549B題解

Jefferyzzzz發表於2024-10-04

傳送門:https://codeforces.com/problemset/problem/549/B

和CF242C思路完全相同,對於一個點,顯然一旦達到額定值後,其他任何操作都無法使他減小,於是我們得出一個貪心性質,當且僅當一個點不合法時,才取增加他的值。同理,我們可以證明,問題必定有解,因為若一個點被選擇,必定是因為其曾不合法,選擇後使其
合法,而若最後一個點不合法,其必定是未選擇的,選擇其則能合法。過程可以用佇列維護。時間複雜度\(O(n)\)

#include <bits/stdc++.h>

using namespace std;

inline int read() {
    char c;
    bool flag = false;
    while ((c = getchar()) < '0' || c > '9') if (c == '-') flag = true;
    int res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + c - '0';
    return flag ? -res : res;
}

vector<int> e[101];
char s[101];
int a[101];

int main() {
    int n = read();
    for (int i = 1; i <= n; ++i) {
        scanf("%s", s + 1);
        for (int j = 1; j <= n; ++j) if (s[j] == '1') e[i].push_back(j);
    }
    vector<int> ans;
    queue<int> q;
    for (int i = 1; i <= n; ++i) {
        a[i] = read();
        if (!a[i]) q.push(i);
    }
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        ans.push_back(x);
        for (int y: e[x]) {
            --a[y];
            if (!a[y]) q.push(y);
        }
    }
    sort(ans.begin(), ans.end());
    printf("%zu\n", ans.size());
    for (int k: ans) printf("%d ", k);
    return 0;
}