有没有同卡68分的呀,求助大佬
查看原帖
有没有同卡68分的呀,求助大佬
216905
泽犴楼主2020/8/23 18:55
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,tot,x,y,a,b;
const ll INF=1ll<<60;
char s[15];
ll q[100005];
int first[100005],dep[100005];
ll dp[100005][2];
int f[100005][20];
ll re[100005][20][2][2];
ll h[100005][2],ans=0;
struct data
{
	int to,nex;
}l[200005];
void edge(int x,int y)
{
	l[++tot].to=y;
	l[tot].nex=first[x];
	first[x]=tot;
}
void dfsdp(int x,int fa)
{
	dp[x][0]=0,dp[x][1]=q[x];
	for(int i=first[x];i;i=l[i].nex)
	{
		int to=l[i].to;
		if(to==fa)continue;
		dfsdp(to,x);
		dp[x][1]+=min(dp[to][1],dp[to][0]);
		dp[x][0]+=dp[to][1];
	}
} 
void dfs(int x,int fa)
{
	for(int i=1;i<=19;i++)
	{
		int tmp=f[x][i-1];
		f[x][i]=f[tmp][i-1];
		for(int u=0;u<2;u++)
		for(int v=0;v<2;v++)
		{
			re[x][i][u][v]=INF;
			for(int w=0;w<2;w++)
			re[x][i][u][v]=min(re[x][i][u][v],re[x][i-1][u][w]+re[tmp][i-1][w][v]);
		}
	}
	for(int i=first[x];i;i=l[i].nex)
	{
		int to=l[i].to;
		if(to==fa)continue;
		h[to][0]=h[x][1]+dp[x][1]-min(dp[to][0],dp[to][1]); 
		h[to][1]=min(h[x][0]+dp[x][0]-dp[to][1],h[to][0]);//未加q[to](统一在lca处理)
		           //父亲不放                    //父亲放 
		dep[to]=dep[x]+1;
		f[to][0]=x;
		//to到x  //[]to放不放 []x放不放 
		re[to][0][0][0]=INF;
		re[to][0][1][0]=dp[x][0]-dp[to][1];//未加q[to] 
		re[to][0][0][1]=dp[x][1]-min(dp[to][1],dp[to][0]);
		re[to][0][1][1]=dp[x][1]-min(dp[to][1],dp[to][0]);//未加q[to]
		dfs(to,x);
	}
}
ll LCA(int a,int x,int b,int y)
{
	if(dep[a]>dep[b])swap(a,b),swap(x,y);
	
	if(f[b][0]==a&&x==0&&y==0)return -1;
	
	ll ansa[2]={INF,INF},ansb[2]={INF,INF};
	
	ll tmpa=dp[a][x],tmpb=dp[b][y];//a往下  b往下 
	ansa[x]=tmpa;ansb[y]=tmpb;
	
	for(int i=19;i>=0;i--)
	{
		if(dep[f[b][i]]>=dep[a])
		{
			ll p1=ansb[0],p2=ansb[1]; 
			ansb[0]=min(p1+re[b][i][0][0],p2+re[b][i][1][0]);
			ansb[1]=min(p1+re[b][i][0][1],p2+re[b][i][1][1]);
			b=f[b][i];
		}
	}
	if(a==b)
	return ansb[x]+h[b][x];
	for(int i=19;i>=0;i--)
	{
		if(f[b][i]!=f[a][i])
		{
			ll p1=ansb[0],p2=ansb[1]; 
			ansb[0]=min(p1+re[b][i][0][0],p2+re[b][i][1][0]);
			ansb[1]=min(p1+re[b][i][0][1],p2+re[b][i][1][1]);
			b=f[b][i];
			p1=ansa[0],p2=ansa[1];
			ansa[0]=min(p1+re[a][i][0][0],p2+re[a][i][1][0]);
			ansa[1]=min(p1+re[a][i][0][1],p2+re[a][i][1][1]);
			a=f[a][i];
		}
	}
	ll tmp0=dp[f[a][0]][0]-dp[a][1]-dp[b][1],tmp1=dp[f[a][0]][1]-min(dp[a][1],dp[a][0])-min(dp[b][1],dp[b][1]);
	//cout<<a<<" "<<b<<endl;
	//cout<<ansa[0]<<" "<<ansa[1]<<" "<<ansb[0]<<" "<<ansb[1]<<endl;
	return min(min(ansa[1],ansa[0])+min(ansb[0],ansb[1])+h[f[a][0]][1]+tmp1,ansa[1]+ansb[1]+h[f[a][0]][0]+tmp0);
}
int main()
{
	scanf("%d%d%s",&n,&m,&s);
	for(int i=1;i<=n;i++)
	scanf("%lld",&q[i]);
	for(int i=1;i<n;i++)
	scanf("%d%d",&x,&y),edge(x,y),edge(y,x);
	dfsdp(1,0);
	dep[1]=1;
	dfs(1,0);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d%d",&a,&x,&b,&y);
		ans=LCA(a,x,b,y);
		printf("%lld\n",ans);
	}/**/
	return 0;
}
/*
5 3 C3 
2 4 1 3 9 
1 5 
5 2 
5 3 
3 4
2 1 3 1
*/ 
2020/8/23 18:55
加载中...