제출 #490152

#제출 시각아이디문제언어결과실행 시간메모리
4901528e7통행료 (APIO13_toll)C++17
16 / 100
3 ms332 KiB
//Challenge: Accepted #include <iostream> #include <algorithm> #include <vector> #include <utility> #include <bitset> #include <set> #include <queue> #include <stack> #include <assert.h> #include <cmath> #include <iomanip> #include <random> using namespace std; void debug(){cout << endl;}; template<class T, class ...U> void debug(T a, U ... b){cout << a << " ", debug(b ...);}; template<class T> void pary(T l, T r) { while (l != r) cout << *l << " ", l++; cout << endl; }; #define ll long long #define maxn 100005 #define maxc 1005 #define mod 1000000007 #define pii pair<int, int> #define ff first #define ss second #define io ios_base::sync_with_stdio(0);cin.tie(0); struct edge { int u, v, w; edge(){u = v = w = 0;} edge(int x, int y, int z){u = x, v = y, w = z;} }; vector<edge> ed; struct DSU{ int par[maxn]; void init(int n) { for (int i = 1;i <= n;i++) par[i] = i; } int find(int a) { return a == par[a] ? a : (par[a] = find(par[a])); } void Union(int a, int b) { // set par[a] = b par[find(a)] = find(b); } } dsu, comp, built; bool mark[maxn]; int vis[maxn]; int wei[maxc], pa[maxc], dep[maxc]; int minres[maxc][maxc]; // minres: minimum restricting edge weight int c[maxn]; ll p[maxc], siz[maxc]; vector<pii> small[maxc]; void dfs(int n, int par, int d, ll &ans) { //builds small tree sizes siz[n] = p[n]; pa[n] = par; dep[n] = d; for (auto v:small[n]) { if (v.ff != par) { dfs(v.ff, n, d+1, ans); siz[n] += p[v.ff]; if (v.ss) ans += siz[v.ff] * wei[v.ff]; } } } void addedge(int a, int b, int val) { //updates added edges if (dep[a] < dep[b]) swap(a, b); while (dep[a] > dep[b]) { wei[a] = min(wei[a], val); a = pa[a]; } while (a != b) { wei[a] = min(wei[a], val), wei[b] = min(wei[b], val); a = pa[a], b = pa[b]; } } int main() { io int n, m, k; cin >> n >> m >> k; for (int i = 0;i < m;i++) { int u, v, w; cin >> u >> v >> w; ed.push_back(edge(u, v, w)); } sort(ed.begin(), ed.end(), [&](edge x, edge y){return x.w < y.w;}); dsu.init(n); built.init(n); vector<edge> add, tree, rep; for (int i = 0;i < k;i++) { int u, v; cin >> u >> v; mark[u] = mark[v] = 1; built.Union(u, v); add.push_back(edge(u, v, 0)); } for (int i = 1;i <= n;i++) cin >> c[i]; for (auto e:ed) { e.u = dsu.find(e.u), e.v = dsu.find(e.v); if (e.u != e.v) { dsu.Union(e.u, e.v); tree.push_back(e); } } dsu.init(n); int ind = n; for (int i = 1;i <= n;i++) p[i] = c[i]; /* for (auto e:tree) { e.u = dsu.find(e.u), e.v = dsu.find(e.v); if (mark[e.u] && mark[e.v]) { if (built.find(e.u) == built.find(e.v)) rep.push_back(e); else { built.Union(e.u, e.v); dsu.Union(e.u, e.v); } } else if (mark[e.u] || mark[e.v]) { if (mark[e.u]) swap(e.u, e.v); dsu.Union(e.u, e.v); } else { dsu.Union(e.u, e.v); } } for (int i = 1;i <= n;i++) { int f = dsu.find(i); if (!vis[f]) { vis[f] = ++ind; } p[vis[f]-1] += c[i]; } for (auto &e:add) { e.u = vis[dsu.find(e.u)]-1, e.v = vis[dsu.find(e.v)]-1; } //debug(); for (auto &e:rep) { e.u = vis[dsu.find(e.u)]-1, e.v = vis[dsu.find(e.v)]-1; if (!minres[e.u][e.v]) minres[e.u][e.v] = minres[e.v][e.u] = e.w; } assert(ind <= maxc); */ ll ans = 0; for (int i = 1;i < (1<<k);i++) { for (int j = 1;j <= n;j++) small[j].clear(), wei[j] = 1<<30; comp.init(ind); bool cy = 0; for (int j = 0;j < k;j++) { if (i & (1<<j)) { small[add[j].u].push_back({add[j].v, 1}); small[add[j].v].push_back({add[j].u, 1}); if (comp.find(add[j].u) == comp.find(add[j].v)) { cy = 1; break; } comp.Union(add[j].u, add[j].v); } } if (cy) continue; vector<edge> lim; for (auto e:tree) { int x = e.u, y = e.v; if (comp.find(x) == comp.find(y)) { lim.push_back(e); } else { comp.Union(x, y); small[x].push_back({y, 0}); small[y].push_back({x, 0}); } } //pary(lim, lim + rs); ll tmp = 0; dfs(1, 0, 0, tmp); for (auto e:lim) addedge(e.u, e.v, e.w); tmp = 0; dfs(1, 0, 0, tmp); ans = max(ans, tmp); debug(); } cout << ans << endl; } /* 5 5 1 3 5 2 1 2 3 2 3 5 2 4 4 4 3 6 1 3 10 20 30 40 50 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...