社区讨论

95pts,求调!!!真的要疯了......

P2680[NOIP 2015 提高组] 运输计划参与者 4已保存回复 10

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
10 条
当前快照
1 份
快照标识符
@mhjhq4rp
此快照首次捕获于
2025/11/04 02:45
4 个月前
此快照最后确认于
2025/11/04 02:45
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m;
int maxn;
ll p[300005][21],d[300005],dis[300005],val[300005],dif[300005];
vector<pair<int,int>> G[300005];
struct node{
    int from,to,Lca,len;
}edge[300005];
void dfs(int u,int f)
{
    p[u][0]=f;
    d[u]=d[f]+1;
    for(int i=1;i<20;i++)
    {
        p[u][i]=p[p[u][i-1]][i-1];
    }
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i].first,w=G[u][i].second;
        if(v==f)continue;
        dis[v]=dis[u]+w;
        val[v]=w;
        dfs(v,u);
    }
}
int LCA(int a,int b)
{
	if(d[a]>d[b])
	{
		swap(a,b);
	}
	for(int i=19;i>=0;i--)
	{
		if(d[b]-(1<<i)>=d[a])
		{
			b=p[b][i];
		}
	}
	if(a==b)return a;
	for(int i=19;i>=0;i--)
	{
		if(p[a][i]!=p[b][i])
		{
			a=p[a][i];
			b=p[b][i];
		}
	}
	return p[a][0];
}
int get(int u,int v,int lca)
{
    return dis[u]+dis[v]-2*dis[lca];
}
void dfs2(int u, int f) {
    for (int i=0;i<G[u].size();i++) {
        int v=G[u][i].first;
        if (v == f) continue;
        dfs2(v, u);
        dif[u] += dif[v];
    }
}
bool check(int mid)
{
    memset(dif,0,sizeof dif);
    int cnt = 0, maxl = 0;
    for (int i = 1; i <= m; i++) {
        if (edge[i].len > mid) {
            cnt++;
            maxl = max(maxl, edge[i].len);
            int u = edge[i].from, v = edge[i].to, w = edge[i].Lca;
            dif[u]++;
            dif[v]++;
            dif[w] -= 2;
        }
    }
    if (cnt == 0) return true;
    dfs2(1, 0);
    for (int i = 1; i <= n; i++) {
        if (dif[i] == cnt && val[i] >= maxl - mid) {
            return true;
        }
    }
    return false;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<n;i++)
    {
        int a,b,t;
        cin>>a>>b>>t;
        G[a].push_back({b,t});
        G[b].push_back({a,t});
    }
    dfs(1,0);
    for(int i=1;i<=m;i++)
    {
        cin>>edge[i].from>>edge[i].to;
        edge[i].Lca=LCA(edge[i].from,edge[i].to);
        edge[i].len=get(edge[i].from,edge[i].to,edge[i].Lca);
        maxn=max(maxn,edge[i].len);
    }
    int l=0,r=maxn;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid))
        {
            r=mid;
        }else{
            l=mid+1;
        }
    }
    cout<<l<<"\n";
    return 0;
}

回复

10 条回复,欢迎继续交流。

正在加载回复...