【BZOJ3322】【洛谷P3280】【SCOI2013】摩托车交易(Kruscal重构树+贪心)

BZOJ传送门

洛谷传送门

这道题和NOIPNOIP的那道货车运输有区别吗

做一个KruscalKruscal重构树就可以了

每次贪心暴力尽量选就是了

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	char ch=getchar();
	int res=0,f=1;
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
	return res*f;
}
#define ll long long
const int N=300005;
const ll inf=1000000000000000ll;
int n,m,adj[N],nxt[N<<3],to[N<<3],fa[N<<1],f[N<<1],cnt,dep[N<<1],siz[N<<1],top[N<<1],son[N<<1],tot,q;
int pr[N],fi;
ll b[N],val[N<<1];
struct edge{
	int u,v;ll w;
}e[N<<1];
inline bool comp(const edge&a,const edge &b){
	return a.w>b.w;
}
inline void addedge(int u,int v)  {
	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
}
void dfs1(int u){
	siz[u]=1;
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(v==fa[u])continue;
		fa[v]=u,dep[v]=dep[u]+1;
		dfs1(v),siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int tp){
	top[u]=tp;
	if(!son[u])return;
	dfs2(son[u],tp);
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}
int find(int x){
	return f[x]==x?f[x]:f[x]=find(f[x]);
}
inline int Lca(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])v=fa[top[v]];
		else u=fa[top[u]];
	}
	return dep[u]<dep[v]?u:v;
}
int main(){
	tot=n=read(),m=read(),q=read();
	for(int i=1;i<=n;i++)f[i]=i;
	for(int i=1;i<=n;i++)pr[i]=read();
	for(int i=1;i<=n;i++)b[i]=read();
	for(int i=1;i<=m;i++){
		e[i].u=read(),e[i].v=read(),e[i].w=read();
	}
	if(q)fi=read();
	for(int i=2;i<=q;i++){
		e[++m].u=fi,e[m].v=read(),e[m].w=inf;
	}
	sort(e+1,e+m+1,comp);
	for(int i=1;i<=m;i++){
		int f1=find(e[i].u),f2=find(e[i].v);
		if(f1!=f2){
			f[f1]=f[f2]=f[++tot]=tot;
			val[tot]=e[i].w;
			addedge(f1,tot),addedge(f2,tot);
			addedge(tot,f1),addedge(tot,f2);
		}
	}
	dfs1(tot),dfs2(tot,tot);
	int plc;ll now=0;
	plc=pr[1];
	if(b[pr[1]]>0)now=b[pr[1]];
	else cout<<0<<'\n';
	for(int i=2;i<=n;i++){
		now=min(now,val[Lca(pr[i],plc)]);
		if(b[pr[i]]>0)now+=b[pr[i]];
		else {
			b[pr[i]]=-b[pr[i]];
			cout<<min(b[pr[i]],now)<<'\n';
			now=max(now-b[pr[i]],(ll)0);
		}
		plc=pr[i];
	}
}

posted @ 2019-01-25 22:03  Stargazer_cykoi  阅读(90)  评论(0编辑  收藏  举报