QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#162615#239. Maximum Weighted MatchingSolitaryDream#100 ✓553ms31164kbC++143.0kb2023-09-03 15:11:182023-09-03 15:11:19

Judging History

你现在查看的是最新测评结果

  • [2023-09-03 15:11:19]
  • 评测
  • 测评结果:100
  • 用时:553ms
  • 内存:31164kb
  • [2023-09-03 15:11:18]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
const int p = 1e9 + 7;
int n, m;
struct Info {
    int wei, num;
};
Info Merge(Info u, Info v) {
    return {u.wei + v.wei, (int)(1ll * u.num * v.num % p)};
}
Info Max(Info u, Info v) {
    if (v.wei == u.wei) return {u.wei, (u.num + v.num) % p};
    return (u.wei > v.wei ? u : v);
}
struct Edge {
    Info f[2][2];
    Edge() {
        f[0][1] = f[1][0] = f[0][0] = f[1][1] = {(int)-1e9, 0};
    }
    Edge(int x, int y, int z) {
        f[0][0] = {0, 1};
        f[0][1] = f[1][0] = {(int)-1e9, 0};
        f[1][1] = {z, 1};
    }
};
map<int, Edge> g[N];
Edge Par(Edge u, Edge v) {
    Edge ans;
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 2; ++j)
            for (int k = 0; k < 2; ++k) if (i + k <= 1)
                for (int l = 0; l < 2; ++l) if (j + l <= 1) {
                    ans.f[i + k][j + l] = Max(ans.f[i + k][j + l], Merge(u.f[i][j], v.f[k][l]));
                }
    return ans;
}
Edge Ser(Edge u, Edge v) {
    Edge ans;
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 2; ++j)
            for (int k = 0; k < 2; ++k) if (j + k <= 1)
                for (int l = 0; l < 2; ++l) {
                    ans.f[i][l] = Max(ans.f[i][l], Merge(u.f[i][j], v.f[k][l]));
                }
    return ans;
}
Edge Flip(Edge u) {
    Edge ans;
    for (int i = 0; i < 2; ++i) 
        for (int j = 0; j < 2; ++j) 
        ans.f[i][j] = u.f[j][i];
    return ans;
}
inline void Adde(int x, int y, Edge z) {
    auto it = g[x].lower_bound(y);
    if (it == g[x].end() || it->first != y) g[x].insert(it, {y, z});
    else it->second = Par(it->second, z);
}
signed main() {
    int Case;
    scanf("%lld", &Case);
    while (Case--) {
        scanf("%lld%lld", &n, &m);
        for (int i = 1, x, y, z; i <= m; ++i) {
            scanf("%lld%lld%lld", &x, &y, &z);
            Adde(x, y, Edge(x, y, z));
            Adde(y, x, Edge(y, x, z));
        }
        queue<int> q;
        for (int i = 1; i <= n; ++i) if (g[i].size() == 2) q.push(i);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            if (g[u].size() != 2) continue;
            auto [x, ex] = *g[u].begin();
            auto [y, ey] = *--g[u].end();
            g[x].erase(u);
            g[y].erase(u);
            g[u].clear();
            Adde(x, y, Ser(Flip(ex), ey));
            Adde(y, x, Ser(Flip(ey), ex));
            if (g[x].size() == 2) q.push(x);
            if (g[y].size() == 2) q.push(y);
        }
        for (int i = 1; i <= n; ++i) if (g[i].size()) {
            auto [y, ey] = *g[i].begin();
            Info ans({(int)-1e9, 0});
            // printf("- %lld %lld\n", i, y);
            for (int i = 0; i < 2; ++i)
                for (int j = 0; j < 2; ++j)
                ans = Max(ans, ey.f[i][j]);
            printf("%lld %lld\n", ans.wei, ans.num);
            break;
        }
        for (int i = 1; i <= n; ++i) g[i].clear();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 553ms
memory: 31164kb

input:

6676
6 10
6 1 1
6 4 1
4 1 1
6 5 1
5 1 1
6 3 1
3 2 1
2 4 1
6 4 1
4 1 1
7 10
4 2 1
4 1 1
1 2 1
1 6 1
6 2 1
1 3 1
3 2 1
1 5 1
5 7 1
7 2 1
7 10
5 3 1
5 7 1
7 2 1
2 3 1
2 1 1
1 4 1
4 3 1
5 6 1
6 7 1
2 3 1
7 10
3 5 1
3 4 1
4 2 1
2 5 1
2 6 1
6 5 1
2 7 1
7 5 1
2 1 1
1 6 1
7 10
5 1 1
5 3 1
3 2 1
2 1 1
2 7 1
...

output:

3 5
3 6
3 14
3 10
3 11
2 13
2 16
3 6
3 3
3 9
2 9
2 14
4 5
3 10
3 13
3 4
3 5
3 14
3 5
2 15
3 10
3 3
3 3
3 14
2 3
3 6
3 3
3 6
3 11
3 17
3 7
3 2
3 6
3 13
3 9
3 11
3 14
3 6
3 2
2 2
2 11
4 4
3 6
3 6
3 5
3 11
2 10
3 5
4 5
2 18
3 13
3 5
3 3
3 12
3 9
2 11
3 2
3 3
3 4
2 7
3 3
3 3
3 2
3 8
3 10
2 15
3 3
3 12
3...

result:

ok 6676 lines