제출 #445096

#제출 시각아이디문제언어결과실행 시간메모리
445096zxcvbnmPipes (BOI13_pipes)C++14
100 / 100
315 ms52036 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxN = 1e5 + 5;
vector<int> need, curr;
vector<pair<int, int>> adj[maxN];
vector<int> in;
vector<int> ans;
void tree(int n) {
    queue<int> q;
    vector<bool> vis(n, false);
    for(int i = 0; i < n; i++) {
        if (in[i] == 1) {
            q.push(i);
        }
    }

    while(!q.empty()) {
        int v = q.front();
        q.pop();
        vis[v] = true;

        for(auto u : adj[v]) {
            if (vis[u.first]) continue;

            ans[u.second] = (need[v] - curr[v]) * 2;
            curr[u.first] += ans[u.second] / 2;
            curr[v] += ans[u.second] / 2;

            in[u.first]--;
            if (in[u.first] == 1) {
                q.push(u.first);
            }
        }
        assert(curr[v] == need[v]);
    }
}
void cant() {
    cout << "0\n";
    exit(0);
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    need.resize(n);
    curr.assign(n, 0);
    in.assign(n, 0);
    ans.assign(n, 0);
    for(int& i : need) {
        cin >> i;
    }

    map<pair<int, int>, int> edges;
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        x--, y--;
        adj[x].push_back({y, i});
        adj[y].push_back({x, i});
        edges[{x, y}] = i;
        in[x]++;
        in[y]++;
    }

    if (m == n-1) {
        tree(n);
        for(int i = 0; i < m; i++) {
            cout << ans[i] << "\n";
        }
        exit(0);
    } else if (m != n) {
        cant();
    }

    queue<int> q;
    vector<bool> vis(n, false);
    for(int i = 0; i < n; i++) {
        if (in[i] == 1) {
            q.push(i);
        }
    }

    while(!q.empty()) {
        int v = q.front();
        q.pop();
        vis[v] = true;

        for(auto u : adj[v]) {
            if (vis[u.first]) continue;

            in[u.first]--;
            ans[u.second] = (need[v] - curr[v]) * 2;
            curr[u.first] += ans[u.second] / 2;
            curr[v] += ans[u.second] / 2;

            if (in[u.first] == 1) {
                q.push(u.first);
                vis[u.first] = true;
            }
        }
    }

    // even cycle
    if (count(vis.begin(), vis.end(), false) % 2 == 0) {
        cant();
    }

    int from = -1, to = -1;
    queue<int>().swap(q);

    for(int i = 0; i < n; i++) {
        if (!vis[i]) {
            q.push(i);
            from = i;
            vis[from] = true;
            for(auto u : adj[from]) {
                if (!vis[u.first]) {
                    to = u.first;
                    break;
                }
            }
            vis[to] = true;
            break;
        }
    }
    assert(from != -1 && to != -1);

    vector<int> cycle;
    cycle.push_back(from);
    while(!q.empty()) {
        int v = q.front();
        q.pop();

        for(auto u : adj[v]) {
            if (!vis[u.first]) {
                cycle.push_back(u.first);
                vis[u.first] = true;
                q.push(u.first);
            }
        }
    }
    cycle.push_back(to);

    // w_from->to
    int w = 0;
    for(int i = 0; i < n; i++) {
        need[i] -= curr[i];
    }

    for(int i = 0; i < (int) cycle.size(); i++) {
        w += need[cycle[i]] * (i % 2 ? -1 : +1);
    }

    ans[edges[{from, to}]] = w;
    reverse(cycle.begin(), cycle.end());

    int prev = cycle[0];
    for(int i = 1; i < (int) cycle.size(); i++) {
        int idx = edges.count({prev, cycle[i]}) == 0 ? edges[{cycle[i], prev}] : edges[{prev, cycle[i]}];
        ans[idx] = 2 * need[prev] - w;
        w = 2 * need[prev] - w;
        prev = cycle[i];
    }

    for(int i = 0; i < n; i++) {
        cout << ans[i] << "\n";
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...