尝试第二篇题解里提到的40分暴力却只有5分求助,关注为报,详细注释,码风优美
查看原帖
尝试第二篇题解里提到的40分暴力却只有5分求助,关注为报,详细注释,码风优美
333800
qip101楼主2022/11/20 22:57
#include <bits/stdc++.h>
#define MAXN 100100
using namespace std;
int n,m,s[MAXN],t[MAXN],sum[MAXN];
struct edge{
	int v,w;
};
vector <edge> G[MAXN];
void add(int u,int v,int w)//建树 
{
	G[u].push_back((edge){v,w});
	G[v].push_back((edge){u,w});
}
void dfs(int u,int fa,int t)//dfs求点与点之间路径的权值和以及最长的边 
{
	int length=0,max_len=0;//边权和 最长边 
	if(u==t)//到达终点 
	{
		cout << length-max_len << endl;//答案 
		return;
	}
	for(int i=0;i<=G[u].size();i++)
	{
		int to=G[u][i].v;
		if(to==fa)
			continue;
		dfs(to,u,t);
		length+=G[u][i].w;//更新 
		max_len=max(max_len,G[u][i].w);
	}
}
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n >> m;
	for(int i=1;i<=n-1;i++)
	{
		int u,v,w;
		cin >> u >> v >> w;
		sum[v]=sum[u]+w;//全是链的话,用前缀和优化计算边权和的过程 
		add(u,v,w);
	}
	for(int i=1;i<=m;i++)
		cin >> s[i] >> t[i];
	if(m==1) 
		dfs(s[1],0,t[1]);
	else//全是链的情况 
	{
		int answer=0;//答案 
		for(int i=1;i<=n-1;i++)//枚举每一个边,暴力删边 
		{
			int res=0,wor=G[i][i+1].w;
			G[i][i+1].w=0;//删边 
			for(int j=1;j<=m;j++)
			{
				int tot=abs(sum[t[j]]-sum[s[j]]);
				if(i<=t[i] && i>=s[j])
					tot-=wor;
				res=max(res,tot);
				//找出最长链即为目前所需时间 
			}
			G[i][i+1].w=wor;//类似回溯 
			answer=min(answer,res);//更新 
		}
		cout << answer << endl;
	}
	return 0;
}
2022/11/20 22:57
加载中...