80Pts玄关求卡常
查看原帖
80Pts玄关求卡常
601236
_WHITE_NIGHT_楼主2024/8/20 08:40
#include <bits/stdc++.h>
using namespace std;

namespace FastIO
{
	const int Mt = 1e5;
	inline char getch()
	{
		static char buf[Mt],*p1 = buf,*p2 = buf;
		return p1 == p2 && (p2 = (p1 = buf) + fread(buf,1,Mt,stdin),p1 == p2) ? EOF : *p1++;
	}
	
	inline int input()
	{
		int num = 0,f = 1;
		char ch = getch();
		while(ch < '0' || ch > '9')
		{
			if(ch == '-') f = -1;
			ch = getch();
		}
		while(ch >= '0' && ch <= '9')
		{
			num = (num << 1) + (num << 3) + (ch ^ 48);
			ch = getch();
		}
		return num * f;
	}
	
	inline void printNum(int num)
	{
		if(num >= 10) printNum(num / 10);
		putchar(num % 10 + 48);
	}
	
	inline void print(int num,char ch = ' ')
	{
		if(num < 0) putchar('-'),num = -num;
		printNum(num);
		putchar(ch);
	}
}
using namespace FastIO;

const int N = 3e5 + 5;
const int D = 20;
struct Node { int v,w; };
int n,m,rt;
int dep[N],diss[N],dis[N],pre[N],w[N];
int fa[D][N << 1];
vector <pair <int,int>> deli;
vector <Node> Graph[N];

void getDep(int u,int from,int distance,int depth)
{
    dis[u] = distance,fa[0][u] = from,dep[u] = depth;
    fa[0][u] = from;
    for(int i = 1;(1 << i) <= dep[u];i++)
        fa[i][u] = fa[i - 1][fa[i - 1][u]];
    for(auto edge : Graph[u])
        if(edge.v != from)
        {
            getDep(edge.v,u,distance + edge.w,depth + 1);
            w[edge.v] = edge.w;
        }
}

int lca(int u,int v)
{
    if(dep[u] < dep[v]) swap(u,v);
    int dif = dep[u] - dep[v];
    for(int i = D - 1;i >= 0;i--)
        if(dif >= (1 << i))
            dif -= (1 << i),u = fa[i][u];
    if(u == v) return u;

    for(int i = D - 1;i >= 0;i--)
        if(fa[i][u] != fa[i][v])
            u = fa[i][u],v = fa[i][v];
    
    return fa[0][u];
}

void dfs(int u,int from)
{
    for(auto edge : Graph[u])
    {
        int v = edge.v;
        if(v == from) continue;
        dfs(v,u);
        pre[u] += pre[v];
    }
}

bool check(int mid)
{
    int cnt = 0;
    for(int i = 1;i <= n;i++)   
        pre[i] = 0;
    // cout << mid << endl;
    for(auto tmp : deli)
    {
        int u = tmp.first,v = tmp.second;
        int ace = lca(u,v);
        if(dis[u] + dis[v] - dis[ace] * 2 > mid)
            cnt++,pre[u]++,pre[v]++,pre[ace] -= 2;
        // cout << u << " " << v << " " << dis[u] + dis[v] - dis[ace] * 2 << endl;
    }
    dfs(rt,-1);
    // cout << "cnt = " << cnt << endl;
    if(!cnt) return 1;
    vector <int> v;
    for(int i = 1;i <= n;i++)
        if(pre[i] == cnt)
            v.push_back(i);
    
    int maxn = -1;
    for(int node : v)
        maxn = max(maxn,w[node]);
    // cout << "maxn = " << maxn << endl;

    for(auto tmp : deli)
    {
        int u = tmp.first,v = tmp.second;
        int ace = lca(u,v);
        if(dis[u] + dis[v] - dis[ace] * 2 - maxn > mid)
            return 0;
    }
    return 1;
}

int main()
{
    srand(time(0));
    n = input(),m = input();
    for(int i = 1;i < n;i++)
    {
        int u = input(),v = input(),w = input();
        Graph[u].push_back({v,w}),Graph[v].push_back({u,w});
    }

    rt = rand() % n + 1;
    // cout << rt << endl;
    getDep(rt,0,0,1);

    int l = 0,r = -1,mid;
    for(int i = 1,u,v;i <= m;i++)
        deli.push_back({u = input(),v = input()}),
        r = max(r,dis[u] + dis[v] - 2 * dis[lca(u,v)]);

    while(l < r)
    {
        mid = l + r >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    print(l);
}
2024/8/20 08:40
加载中...