QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#391412 | #6619. Line Graph Matching | tz3528 | WA | 1ms | 5700kb | C++20 | 1.5kb | 2024-04-16 16:14:45 | 2024-04-16 16:14:45 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010, M = 400010;
int head[N], ver[M], nxt[M], edge[M], vis[N];
int dfn[N], low[N], cnt[N], n, m, tot, num;
int Min;
void add(int x, int y, int z) {
ver[++tot] = y, edge[tot] = z, nxt[tot] = head[x], head[x] = tot;
}
void tarjan(int x, int in_edge) {
dfn[x] = low[x] = ++num;
for (int i=head[x]; i; i = nxt[i]) {
int y = ver[i];
if (!dfn[y]) {
tarjan(y, i);
cnt[x] += cnt[y] + 1; // x 所在的连通分量边数增加
low[x] = min(low[x], low[y]);
if (low[y] > dfn[x]) {
if (cnt[y] % 2 == 0) { // 如果该边是割边,那么要判断 y 所在连通分量边数是否为偶数
Min = min(Min, edge[i]);
}
}
else { // 如果不是割边,则不需要限制
Min = min(Min, edge[i]);
}
}
else { // 如果出现返祖边,即搜索树中,子孙指向祖先的边
if(dfn[x] > dfn[y]) { // 这条边记录到时间戳更大的点上(只是为了防止重复计数)
cnt[x] ++;
}
low[x] = min(low[x], dfn[y]);
Min = min(Min, edge[i]);
}
}
}
int main() {
scanf("%d%d", &n, &m);
tot = 1;
ll res = 0;
for (int i = 1; i <= m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
add(x, y, z); add(y, x, z);
res += z;
}
Min = 1e9; // 如果要删边,Min 记录可以删除的边中的最小权值
tarjan(1, 0);
if(m & 1) res -= Min;
cout << res << endl;
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 5688kb
input:
5 6 1 2 1 1 3 2 1 4 3 4 3 4 4 5 5 2 5 6
output:
21
result:
ok 1 number(s): "21"
Test #2:
score: -100
Wrong Answer
time: 1ms
memory: 5700kb
input:
6 5 1 2 4 2 3 1 3 4 3 4 5 2 5 6 5
output:
14
result:
wrong answer 1st numbers differ - expected: '12', found: '14'