QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#137148#239. Maximum Weighted MatchingBoulevardDust100 ✓474ms15740kbC++145.9kb2023-08-09 23:34:212023-08-09 23:34:23

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-08-09 23:34:23]
  • 评测
  • 测评结果:100
  • 用时:474ms
  • 内存:15740kb
  • [2023-08-09 23:34:21]
  • 提交

answer

#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <utility>
#include <vector>
#define ll long long
#define pii pair<int, int>
#define mn 100005
#define p 1000000007

using namespace std;

const ll inf = 1000000000000000000ll;

int T, n, m, in[mn], vis[mn], pre[mn];

struct edge {
    int u, v, w;
}ed[mn];
vector<pii > e[mn];

// vector<int> elist;

void inc(int &a, int b) {
    if((a += b) >= p) a -= p;
}
struct Ans {
    ll v; int c;
    void upd(Ans a, int w) {
        if(v < a.v + w) {
            v = a.v + w, c = a.c;
        }
        else if(v == a.v + w) {
            inc(c, a.c);
        }
    }
    void upd(pair<ll, int> b, int w) {
        return upd((Ans){b.first, b.second}, w);
    }
    Ans operator+(const Ans &a) const {
        return (Ans){v + a.v, (int)(1ll * c * a.c % p)};
    }
};

struct F {
    Ans f[2][2];
    F() {
        for(int i = 0; i < 2; ++i) {
            for(int j = 0; j < 2; ++j) {
                f[i][j] = (Ans){-inf, 1};
            }
        }
        f[0][0] = (Ans){0ll, 1};
    }
    void clear() {
        f[0][0] = f[0][1] = f[1][0] = f[1][1] = (Ans){0ll, 0};      
    }
};


int q[mn];
F dp(int eid, int u, int v) {
    // printf("u v %d %d\n", u, v);
    vector<F> vres;
    vis[eid] = 1;
    while(1) {
        int hd = 0, tl = 1;
        q[1] = u, in[u] = 1, in[v] = 0;
        while(hd < tl) {
            int x = q[++hd];
            for(int i = 0; i < (int)e[x].size(); ++i) if(!vis[e[x][i].second] && !in[e[x][i].first]) {
                q[++tl] = e[x][i].first, in[e[x][i].first] = 1, pre[e[x][i].first] = e[x][i].second;
            }
            if(in[v]) break;
        }
        int fl = in[v];
        // printf("%d %d %d\n", tl, q[1], q[2]);
        for(int i = 1; i <= tl; ++i) {
            in[q[i]] = 0;
        }
        if(!fl) {
            in[u] = in[v] = 1;
            break;
        }
        // puts("233");

        // printf("u v %d %d %d\n", u, v, tl);
        // for(int i = 1; i <= tl; ++i) {
        //     printf("%d ", q[i]);
        // }
        // puts("");
        // for(int i = 1; i <= n; ++i) {
        //     printf("%d %d %d %d\n", i, pre[i], ed[pre[i]].u, ed[pre[i]].v);
        // }
        vector<int> vlist;
        int x = v;
        vlist.push_back(v);
        while(x != u) {
        // puts("233");    
            int y = ed[pre[x]].u + ed[pre[x]].v - x;
            // printf("%d %d\n", x, y);
            vis[pre[x]] = 1;
            vlist.push_back(y);
            x = y;
        }
        // printf("vlist(%d %d)\n", u, v);
        for(int i = 0; i < (int)vlist.size(); ++i) {
            in[vlist[i]] = 1;
            // printf("%d ", vlist[i]);
        }
        // puts("");

        F res;
        vector<int> pret;
        for(int i = 0; i < (int)vlist.size() - 1; ++i) {
            pret.push_back(pre[vlist[i]]);
        }
        for(int i = 0; i < (int)vlist.size() - 1; ++i) {
            // int x = vlist[i];
            F f = dp(pret[i], vlist[i], vlist[i + 1]);
            if(i == 0) {
                res = f;
                continue;
            }
            F t = res;
            res.clear();
            for(int a = 0; a <= 1; ++a) {
                for(int b = 0; b <= 1; ++b) {
                    for(int c = 0; c <= 1; ++c) {
                        if(b && c) continue;
                        for(int d = 0; d <= 1; ++d) {
                            res.f[a][d].upd(t.f[a][b] + f.f[c][d], 0);
                        }
                    }
                }
            }
            // printf("res(%d %d) v: %lld %lld %lld %lld\n", u, v, res.f[0][0].v, res.f[0][1].v, res.f[1][0].v, res.f[1][1].v);
            // printf("res(%d %d) c: %d %d %d %d\n", u, v, res.f[0][0].c, res.f[0][1].c, res.f[1][0].c, res.f[1][1].c);
        }
        vres.push_back(res);
    }
    // if(!vres.empty()) printf("%d\n", vres[0].f[0][0].c);
    F Res;
    for(int i = 0; i < (int)vres.size(); ++i) {
        F t = Res;
        Res.clear();
        for(int a = 0; a <= 1; ++a) {
            for(int b = 0; b <= 1; ++b) {
                for(int c = 0; c <= 1; ++c) {
                    for(int d = 0; d <= 1; ++d) {
                        if(a + c <= 1 && b + d <= 1) {
                            Res.f[a + c][b + d].upd(t.f[a][b] + vres[i].f[c][d], 0);
                        }
                    }
                }
            }
        }
    }
    // printf("%d\n", ed[eid].w);
    Res.f[1][1].upd(Res.f[0][0], ed[eid].w);
    swap(Res.f[1][0], Res.f[0][1]);
    // printf("Res(%d %d) v: %lld %lld %lld %lld\n", u, v, Res.f[0][0].v, Res.f[0][1].v, Res.f[1][0].v, Res.f[1][1].v);
    // printf("Res(%d %d) c: %d %d %d %d\n", u, v, Res.f[0][0].c, Res.f[0][1].c, Res.f[1][0].c, Res.f[1][1].c);
    return Res;
}

int main() {
    // freopen("test.in", "r", stdin);
    scanf("%d", &T);
    // int o = 0;
    while(T--) {
        // ++o;
        scanf("%d%d", &n, &m);
        // for(int i = 1; i <= n; ++i) {
        //  vis[i] = 0;
        // }
        for(int i = 1; i <= n; ++i) {
            in[i] = 0;
            e[i].clear();
        }
        for(int i = 1; i <= m; ++i) {
            scanf("%d%d%d", &ed[i].u, &ed[i].v, &ed[i].w);
            e[ed[i].u].push_back(make_pair(ed[i].v, i)),
            e[ed[i].v].push_back(make_pair(ed[i].u, i));
            vis[i] = 0;
        }
        // if(o == 1003) {
        //     printf("%d %d\n", n, m);
        //     for(int i = 1; i <= m; ++i) {
        //         printf("%d %d %d\n", ed[i].u, ed[i].v, ed[i].w);
        //     }
        // }
        // vis[ed[1].u] = vis[ed[1].v] = 1;
        F f = dp(1, ed[1].u, ed[1].v);
        Ans ans = (Ans){0ll, 0};
        for(int i = 0; i <= 1; ++i) {
            for(int j = 0; j <= 1; ++j) {
                ans.upd(f.f[i][j], 0);
            }
        }
        printf("%lld %d\n", ans.v, ans.c);
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 474ms
memory: 15740kb

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