1 2 3 4

P4374 [USACO18OPEN]Disruption P

 

https://www.luogu.com.cn/problem/P4374

洛谷这题一言难尽

 

添加新边影响的边只有与新边成环的所有边,那就很简单了,树链剖分树上最大值就行了。。。很简单不知道为啥是紫题

#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn = 2e5+11;
const int INF = 1e9+111;

vector<int>G[maxn];
void add(int be,int en){
	G[be].push_back(en);
}


int n,m;
int top[maxn],id[maxn],cnt,dep[maxn],fa[maxn],siz[maxn],son[maxn];

int dfs(int x,int f,int d) {
	fa[x] = f;
	dep[x] = d;
	siz[x] = 1;
	int s = 0;
	
	for(int i=0; i< G[x].size(); i++) {
		int p = G[x][i];
		if(p == f) continue;
		
		dfs(p,x,d+1);
		siz[x] += siz[p];
		if(s < siz[p]) {
			s = siz[p];
			son[x] = p;
		}
	}
	return 0;
}

int dfs2(int x,int t) {
	id[x] = ++cnt;
	top[x] = t;
	if(son[x] != 0) dfs2(son[x],t);
	for(int i=0; i<G[x].size(); i++) {
		int p =G[x][i];
		if(p == son[x] || p == fa[x]) continue;
		
		dfs2(p,p);
	}
	return 0;
}
//建立线段树
struct Node {
	int ans,lazy;
} tree[maxn*4];

int bulit(int node,int be,int en) {
	int mid =be+en>>1;
	int l = node*2;
	int r = node*2+1;
	if(be == en) {
		tree[node].ans = INF;
		tree[node].lazy = INF;
		return 0;
	}

	tree[node].ans = INF;
	tree[node].lazy = INF;
	bulit(l,be,mid);
	bulit(r,mid+1,en);
	return 0;
}
int push(int node,int be,int en) {
	int mid = be +en >>1;
	int l = node*2;
	int r = node*2+1;
	if(tree[node].lazy != INF) {
		tree[l].ans = min(tree[l].ans , tree[node].lazy);
		tree[r].ans = min(tree[r].ans , tree[node].lazy);

		tree[l].lazy = min(tree[node].lazy,tree[l].lazy);
		tree[r].lazy = min(tree[node].lazy,tree[r].lazy);
		tree[node].lazy = INF;
	}
	return 0;
}
int update(int node,int be,int en,int LL,int RR,int val) {
	if(LL > RR) return 0;
	
	int mid = be +en >>1;
	int l = node*2;
	int r = node*2+1;
	if(LL <= be && en <= RR) {
		tree[node].ans = min(tree[node].ans ,val);
		if(tree[node].lazy != 0) tree[node].lazy = min(tree[node].lazy,val);

		return 0;
	}
	push(node,be,en);
	if(LL <= mid) update(l,be,mid,LL,RR,val);
	if(RR > mid)  update(r,mid+1,en,LL,RR,val);
	tree[node].ans = min(tree[l].ans,tree[r].ans);
	return 0;
}


int ask(int node,int be,int en,int LL,int RR) {
	if(LL > RR) return INF;
	
	int mid = be + en >> 1;
	int l = node*2;
	int r = node*2+1;
	if(LL <= be && en <= RR) {
		return tree[node].ans;
	}
	int a = INF,b = INF;
	push(node,be,en);
	
	if(LL <= mid) a = ask(l,be,mid,LL,RR);
	if(RR > mid)  b = ask(r,mid+1,en,LL,RR);
	return min(a,b);
}


int change(int x,int y,int val) {
	int ans = INF;
	while(top[x] != top[y]) {
		if(dep[top[x]] < dep[top[y]]) swap(x,y);
		update(1,1,n,id[top[x]],id[x],val);
		x = fa[top[x]];
	}
	
	if(dep[x] > dep[y]) swap(x,y);

	update(1,1,n,id[x] + 1,id[y],val);
	return 0;
}



vector<pair<int,int> >ins;
vector<int>ans;

int main() {
//	freopen("in.in","r",stdin);
//	freopen("out.out","w",stdout);
	
	scanf("%d %d",&n,&m);
	for(int i=1; i<n; i++) {
		int be,en;
		scanf("%d%d",&be,&en);
		ins.push_back(make_pair(be,en));
		add(be,en);
		add(en,be);
	}
	dfs(1,-1,1);
	dfs2(1,1);
	bulit(1,1,n);


	while(m--) {
		int x,y,w;
		scanf("%d %d %d",&x,&y,&w);
		change(x,y,w);
	}
	
	for(int i=0;i<ins.size();i++){
		int x = ins[i].first;
		int y = ins[i].second;
		if(dep[x] < dep[y]) swap(x,y);
		
		int a = ask(1,1,n,id[x],id[x]);
		ans.push_back(a);
	}
	
	for(int i=0;i<ans.size();i++){
		if(ans[i] == INF) ans[i] = -1;
		printf("%d\n",ans[i]);
	}
	return 0;
}

  

posted @ 2020-12-12 10:36  Lesning  阅读(69)  评论(0编辑  收藏  举报