Mobile Phone Network CodeForces - 1023F (minimum spanning tree)

Effect: undirected graph, where k is your edges, the edge weights determined, m your opponent's edges, the edge weight is known how to find the right side can set minimum spanning tree, you have all been selected to the edges. and your right side edges and maximum. if there are several minimum spanning trees take priority on your side.

 

Now $ k $ edges merge, and then press the right side from small to large Tim opponent's side, if connectivity is the minimum value chain, tree, or merge it.

In fact, it is clear that correctness.

Then take a variety of methods for tree minimum chain force line tree can sectional $ O (nlog ^ 2n) $, it can be used offline multiplication $ O (nlogn) $, or disjoint-set $ O (n) $.

 

#include <iostream>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#include <bitset>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
#define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int n, k, m, cnt, fa[N];
struct _ {int to,id;} pre[N];
vector<_> g[N];
struct {int u,v,w;} e[N];
int Find(int x) {return fa[x]?fa[x]=Find(fa[x]):x;}
int dep[N], ans[N];

void dfs(int x, int d, int f) {
	dep[x] = d;
	for (_ e:g[x]) if (e.to!=f) { 
		pre[e.to] = {x,e.id};
		dfs(e.to,d+1,x);
	}
}

int main() {
	scanf("%d%d%d", &n, &k, &m);
	int tot = 0;
	while (k--) {
		int u, v;
		scanf("%d%d", &u, &v);
		fa[Find(u)] = Find(v);
		g[u].pb({v,1}),g[v].pb({u,1});
	}
	REP(i,1,m) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		int uu = Find(u), vv = Find(v);
		if (uu==vv) e[++cnt]={u,v,w};
		else {
			fa[uu] = vv;
			g[u].pb({v,0}), g[v].pb({u,0});
		}
	}
	dfs(1,0,0);
	memset(fa,0,sizeof fa);
	REP(i,1,cnt) {
		int u = e[i].u, v = e[i].v, w = e[i].w;
		while (Find(u)!=Find(v)) {
			if (dep[u]<dep[v]) swap(u,v);
			if (Find(u)!=Find(pre[u].to)) {
				fa[u] = Find(pre[u].to);
				ans[u] = w;
			}
			u = Find(u);
		}
	}
	ll sum = 0;
	REP(i,1,n) if (pre[i].to&&pre[i].id) { 
		if (!ans[i]) return puts("-1"),0;
		else sum += ans[i];
	}
	printf("%lld\n", sum);
}

 

Guess you like

Origin www.cnblogs.com/uid001/p/11128080.html