이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define TASK ""
#define bit(x) (1LL << (x))
#define getbit(x, i) (((x) >> (i)) & 1)
#define ALL(x) (x).begin(), (x).end()
using namespace std;
template <typename T1, typename T2> bool mini(T1 &a, T2 b) {
if (a > b) {a = b; return true;} return false;
}
template <typename T1, typename T2> bool maxi(T1 &a, T2 b) {
if (a < b) {a = b; return true;} return false;
}
mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count());
int rand(int l, int r) {
return l + rd() % (r - l + 1);
}
const int N = 1e5 + 5;
const int M = 3e5 + 5;
const int oo = 1e9;
const long long ooo = 1e18;
const int mod = 1e9 + 7; // 998244353;
const long double pi = acos(-1);
vector <int> adj[N];
vector <int> ind;
long long val[N];
int fr[M];
int to[M];
int w[M];
int T[N][5];
int par[N];
int anc[N];
int lim[N];
int tin[N];
int mx[N];
int h[N];
int a[N];
int b[N];
int n,k,m,timer;
int getpar(int u) {
return (par[u] < 0) ? u : (par[u] = getpar(par[u]));
}
bool join(int u, int v) {
u = getpar(u);
v = getpar(v);
if (u == v)
return false;
if (par[u] > par[v])
swap(u, v);
par[u] += par[v];
par[v] = u;
return true;
}
int gethigh(int u, int v) {
return (h[u] < h[v]) ? u : v;
}
void dfs(int u, int p = -1) {
// cerr << val[u] << " " << u << " " << p << "\n";
anc[u] = p;
tin[u] = ++timer;
T[timer][0] = u;
for (int i : adj[u]) {
int v = (i < 0) ? (fr[-i] ^ to[-i] ^ u) : (a[i] ^ b[i] ^ u);
if (v == p)
continue;
int c = (i < 0) ? 0 : mx[i];
lim[v] = c;
T[++timer][0] = u;
h[v] = h[u] + 1;
dfs(v, u);
}
}
int getlca(int u, int v) {
int l = tin[u];
int r = tin[v];
if (l > r)
swap(l, r);
int d = __lg(r - l + 1);
return gethigh(T[l][d], T[r - bit(d) + 1][d]);
}
long long getans(int u, long long cur = 0, int p = -1) {
long long res = cur * val[u];
for (int i : adj[u]) {
int v = (i < 0) ? (fr[-i] ^ to[-i] ^ u) : (a[i] ^ b[i] ^ u);
if (v == p)
continue;
res += getans(v, cur + lim[v], u);
}
return res;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
#ifdef ONLINE_JUDGE
// freopen(TASK".inp","r",stdin);
// freopen(TASK".out","w",stdout);
#endif
cin >> n >> m >> k;
for (int i = 1; i <= m; i++) {
cin >> fr[i] >> to[i] >> w[i];
ind.push_back(i);
}
for (int i = 1; i <= k; i++)
cin >> a[i] >> b[i];
sort(ALL(ind), [](int i, int j) {
return w[i] < w[j];
});
{
memset(par, -1, sizeof(par));
vector <int> newind;
for (int i : ind) {
if (join(fr[i], to[i])) {
newind.push_back(i);
for (int j = 1; j <= k; j++)
if (!mx[j] && getpar(a[j]) == getpar(b[j]))
mx[j] = w[i];
}
}
swap(newind, ind);
}
vector <int> notind;
{
vector <int> newind;
memset(par, -1, sizeof(par));
for (int i = 1; i <= k; i++)
join(a[i], b[i]);
for (int i : ind) {
if (join(fr[i], to[i]))
newind.push_back(i);
else
notind.push_back(i);
}
swap(newind, ind);
}
memset(par, -1, sizeof(par));
for (int i : ind)
join(fr[i], to[i]);
for (int i = 1; i <= n; i++) {
int x; cin >> x;
val[getpar(i)] += x;
}
vector <int> node;
for (int i = 1; i <= n; i++)
if (par[i] < 0)
node.push_back(i);
for (int i : notind) {
fr[i] = getpar(fr[i]);
to[i] = getpar(to[i]);
}
for (int i = 1; i <= k; i++) {
a[i] = getpar(a[i]);
b[i] = getpar(b[i]);
}
long long ans = 0;
int root = getpar(1);
for (int mask = 0; mask < bit(k); mask++) {
for (int v : node) {
par[v] = -1;
adj[v].clear();
}
bool ok = true;
for (int i = 1; i <= k; i++) if (getbit(mask, i - 1)) {
if (!join(a[i], b[i])) {
ok = false;
break;
}
adj[a[i]].push_back(i);
adj[b[i]].push_back(i);
}
if (!ok)
continue;
vector <int> lef;
for (int i : notind) {
if (join(fr[i], to[i])) {
adj[fr[i]].push_back(-i);
adj[to[i]].push_back(-i);
} else {
lef.push_back(i);
}
}
timer = 0;
h[root] = 0;
dfs(root);
for (int j = 1; j < 5; j++)
for (int i = 1; i + bit(j) - 1 <= timer; i++)
T[i][j] = gethigh(T[i][j - 1], T[i + bit(j - 1)][j - 1]);
for (int v : node)
par[v] = -1;
for (int i : lef) {
int p = getlca(fr[i], to[i]);
int v;
{
v = getpar(fr[i]);
while (h[v] > h[p]) {
mini(lim[v], w[i]);
par[v] = anc[v];
v = getpar(v);
}
}
{
v = getpar(to[i]);
while (h[v] > h[p]) {
mini(lim[v], w[i]);
par[v] = anc[v];
v = getpar(v);
}
}
}
maxi(ans, getans(root));
}
cout << ans;
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |