题目

并查集暴力代码 30p
#include <bits/stdc++.h>
using namespace std;
using ll = long long;const int N = 1e5+10;int n, m;
int a[N], p[N];
ll ans = 1e18;
ll s[3];
bool st;struct edge
{int a, b;
} e[N];void init()
{for(int i = 1; i <= n; i++)p[i] = i;
}int find(int x)
{if(p[x] != x) p[x] = find(p[x]);return p[x];
}void check()
{int cnt = 0;int fir = find(1);for(int i = 1; i <= n; i++){if(p[i] == i) cnt++;if(p[i] == fir) s[1] += a[i];else s[2] += a[i];}if(cnt == 2) st = true, ans = min(ans, abs(s[2] - s[1]));
}
int main()
{scanf("%d%d", &n, &m);for(int i = 1; i <= n; i++)scanf("%d", a+i);for(int i = 1; i <= m; i++){int a, b;scanf("%d%d", &a, &b);e[i] = {a, b};}for(int i = 1; i <= m; i++){init(); s[1] = s[2] = 0;for(int j = 1; j <= m; j++){if(i == j) continue;int a = e[j].a, b = e[j].b;int pa = find(a), pb = find(b);if(pa != pb) p[pa] = pb;}check();}if(st) printf("%lld", ans);else puts("-1");
}
正解
#include <bits/stdc++.h>
using namespace std;
using ll = long long;const int N = 2e5+10;
const int M = 4e5+10;int n, m;
int a[N]; //权重
ll f[N]; //子树权重和
int h[N], e[M], ne[M], idx; //链式前向星
ll sum, ans = 1e18; //权重和 答案
int dfn[N], low[N], tot; //时间戳 追溯值 分配器
bool flag; //割边存在性void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}void tarjan(int u, int ine)
{dfn[u] = ++tot, low[u] = tot;f[u] = a[u];for(int i = h[u]; ~i; i = ne[i]){int j = e[i];if(!dfn[j]){tarjan(j, i);f[u] += f[j];low[u] = min(low[u], low[j]);if(low[j] > dfn[u]) //这里放在向下的部分,因为dfn[u]是固定的,向上的部分只会影响到low[u]{ans = min(ans, abs(sum - 2 * f[j]));flag = true;}}else if(i != (ine ^ 1))low[u] = min(low[u], dfn[j]);}
}
int main()
{scanf("%d%d", &n, &m);for(int i = 1; i <= n; i++){scanf("%d", a+i);sum += a[i];}memset(h, -1, sizeof h);for(int i = 1; i <= m; i++){int a, b;scanf("%d%d", &a, &b);add(a, b); add(b, a);}tarjan(1, -1); //调用时,第二个参数随便给if(f[1] != sum) ans = sum - 2 * f[1]; //不是连通图,直接求差(本题默认所给图最多两个连通分量)elseif(!flag) ans = -1; //是连通图,无割边printf("%lld", ans);
}