답안 #54592

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
54592 2018-07-04T07:32:26 Z 강태규(#1489) Training (IOI07_training) C++11
100 / 100
77 ms 4904 KB
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <functional>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>

using namespace std;
typedef long long llong;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<llong, llong> pll;

int n, m, k;
vector<int> edge[1001];

int par[1001][10];
int dep[1001];
vector<int> ps[1001];

void dfs(int x, int p) {
    par[x][0] = p;
    for (int i = 1; i < 10; ++i) {
        par[x][i] = par[par[x][i - 1]][i - 1];
    }
    dep[x] = dep[p] + 1;
    sort(edge[x].begin(), edge[x].end());
    for (int i : edge[x]) {
        if (i == p) continue;
        dfs(i, x);
    }
}

int getPar(int x, int d) {
    for (int i = 10; i--; ) {
        if ((d >> i) & 1) x = par[x][i];
    }
    return x;
}

int getLca(int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    for (int i = 10; i--; ) {
        if ((dep[x] - dep[y]) >> i) x = par[x][i];
    }
    if (x == y) return x;
    for (int i = 10; i--; ) {
        if (par[x][i] != par[y][i]) {
            x = par[x][i];
            y = par[y][i];
        }
    }
    return par[x][0];
}

struct nroad {
    int x, y, c, p;
    void scan() {
        scanf("%d%d%d", &x, &y, &c);
    }
} ns[5000];

int dp[1001][1 << 10];

int find(vector<int> &v, int x) {
    return lower_bound(v.begin(), v.end(), x) - v.begin();
}

int getBitmask(int p, int x, int y) {
    int ret = 0;
    if (p != x) ret |= (1 << find(edge[p], getPar(x, dep[x] - dep[p] - 1)));
    if (p != y) ret |= (1 << find(edge[p], getPar(y, dep[y] - dep[p] - 1)));
    return ret;
}

void dfs2(int x, int p) {
    int sz = edge[x].size();
    for (int i : edge[x]) {
        if (i == p) continue;
        dfs2(i, x);
        int b = getBitmask(x, x, i);
        for (int j = (1 << sz); j--; ) {
            if (b & j) continue;
            dp[x][b | j] = max(dp[x][b | j], dp[x][j] + dp[i][(1 << edge[i].size()) - 1]);
        }
    }
    for (int i : ps[x]) {
        int y = ns[i].x;
        int ans = ns[i].c;
        while (x != y) {
            int b = getBitmask(y, y, ns[i].x);
            ans += dp[y][((1 << edge[y].size()) - 1) ^ b];
            y = par[y][0];
        }
        
        y = ns[i].y;
        while (x != y) {
            int b = getBitmask(y, y, ns[i].y);
            ans += dp[y][((1 << edge[y].size()) - 1) ^ b];
            y = par[y][0];
        }
        int bm = getBitmask(x, ns[i].x, ns[i].y);
        for (int j = (1 << sz); j--; ) {
            if (bm & j) continue;
            dp[x][bm | j] = max(dp[x][bm | j], dp[x][j] + ans);
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    int sum = 0;
    for (int i = 0; i < m; ++i) {
        ns[k].scan();
        if (ns[k].c) sum += ns[k++].c;
        else {
            edge[ns[k].x].push_back(ns[k].y);
            edge[ns[k].y].push_back(ns[k].x);
        }
    }
    dfs(1, 0);
    k = 0;
    for (int i = 0; i <= m - n; ++i) {
        if ((dep[ns[i].x] ^ dep[ns[i].y]) & 1);
        else ns[k++] = ns[i];
    }
    for (int i = 0; i < k; ++i) {
        ns[i].p = getLca(ns[i].x, ns[i].y);
        ps[ns[i].p].push_back(i);
    }
    dfs2(1, 0);
    printf("%d\n", sum - dp[1][(1 << edge[1].size()) - 1]);
    
	return 0;
}

Compilation message

training.cpp: In function 'int main()':
training.cpp:118:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d%d", &n, &m);
     ~~~~~^~~~~~~~~~~~~~~~
training.cpp: In member function 'void nroad::scan()':
training.cpp:66:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d%d", &x, &y, &c);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 504 KB Output is correct
2 Correct 2 ms 616 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 680 KB Output is correct
2 Correct 3 ms 732 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 4660 KB Output is correct
2 Correct 30 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4904 KB Output is correct
2 Correct 2 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4904 KB Output is correct
2 Correct 2 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4904 KB Output is correct
2 Correct 2 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4904 KB Output is correct
2 Correct 3 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 4904 KB Output is correct
2 Correct 5 ms 4904 KB Output is correct
3 Correct 9 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 4904 KB Output is correct
2 Correct 11 ms 4904 KB Output is correct
3 Correct 8 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 4904 KB Output is correct
2 Correct 10 ms 4904 KB Output is correct
3 Correct 52 ms 4904 KB Output is correct
4 Correct 15 ms 4904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 30 ms 4904 KB Output is correct
2 Correct 77 ms 4904 KB Output is correct
3 Correct 32 ms 4904 KB Output is correct
4 Correct 11 ms 4904 KB Output is correct