AC + WA 求调,悬 1 关
查看原帖
AC + WA 求调,悬 1 关
1105993
Misserina楼主2024/11/25 19:35

样例全对

#include <bits/stdc++.h>
using namespace std;
int n,a,b,c,d,ft[200005][20],q1[200005],depth[200005],ed[200005];
long long res,add[200005];
bool marked1[200005],marked2[200005];
struct edge {
	int id,to,c1,c2;
} edges[200005];
vector<edge> v[200005];
int log2(int n) {
	int res=0;
	while (n>1) {
		res++;
		n/=2;
	}
	return res;
}
long long min(long long a,long long b) {
	if (a<b) return a;
	return b;
}
void bfs1() {
	q1[0]=1;
	marked1[1]=1;
	depth[1]=1;
	int l=0,r=1;
	while (l<r) {
		int s=q1[l++];
		for (int i=0;i<v[s].size();i++) {
			int t=v[s][i].to;
			if (!marked1[t]) {
				marked1[t]=1;
				q1[r++]=t;
				depth[t]=depth[s]+1;
				ed[t]=v[s][i].id;///
				ft[t][0]=s;
				for (int i=1;i<log2(depth[t]);i++) {
					ft[t][i]=ft[ft[t][i-1]][i-1];
				}
			}
		}
	}
}
void dfs2(int n) {
	marked2[n]=1;
	for (int i=0;i<v[n].size();i++) {
		int t=v[n][i].to;
		if (!marked2[t]) {
			dfs2(t);
			add[n]+=add[t];
		}
	}
	//printf("%d %d %d %d %d\n",n,ed[n],add[n],edges[ed[n]].c1,edges[ed[n]].c2);
	if (ed[n]>0) res+=min(edges[ed[n]].c2,add[n]*edges[ed[n]].c1);
}
int lca(int a,int b) {
	while (depth[a]>depth[b]) {
		int n=log2(depth[a]-depth[b]);
		a=ft[a][n];
	}
	while (depth[b]>depth[a]) {
		int n=log2(depth[b]-depth[a]);
		b=ft[b][n];
	}
	for (int i=log2(depth[a]);i>=0;i--) {
		if (ft[a][i]!=ft[b][i]) {
			a=ft[a][i];
			b=ft[b][i];
		}
	}
	if (a!=b) a=ft[a][0];
	return a;
}
int main() {
	scanf("%d",&n);
	for (int i=1;i<n;i++) {
		scanf("%d%d%d%d",&a,&b,&c,&d);
		edge ea,eb;
		ea.id=i,ea.to=b,ea.c1=c,ea.c2=d;
		eb.id=i,eb.to=a,eb.c1=c,eb.c2=d;
		v[a].push_back(ea);
		v[b].push_back(eb);
		edges[i].c1=c,edges[i].c2=d;
	}
	bfs1();
	for (int i=2;i<=n;i++) {
		int LCA=lca(i-1,i);
		add[i-1]++;
		add[i]++;
		add[LCA]-=2;
	}
	dfs2(1);
	printf("%lld",res);
}
2024/11/25 19:35
加载中...