2 条题解

  • 2
    @ 2023-7-24 19:36:00
    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 3e5 + 10;
    
    struct edge
    {
    	int v, w;
    	int nxt;
    } e[maxn << 1];
    int n, m,
    ver[maxn], w[maxn], a[maxn], b[maxn], c[maxn], d[maxn], f[maxn], s[maxn], num,
    top[maxn], fa[maxn], size[maxn], son[maxn], dep[maxn], dis[maxn],
    l, r, mid, ans, maxw;
    
    inline void adde(int u, int v, int w)
    {
    	static int ed = 1;
    	e[++ed] = (edge){ v, w, ver[u] };
    	ver[u] = ed;
    }
    
    inline void dfs1(int u, int f)
    {
    	s[++num] = u;
    	size[u] = 1, fa[u] = f;
    	for(int i = ver[u]; i; i = e[i].nxt)
    	{
    		int v = e[i].v;
    		if(size[v])
    			continue;
    		dep[v] = dep[u] + 1;
    		w[v] = e[i].w;
    		dis[v] = dis[u] + w[v];
    		dfs1(v, u);
    		size[u] += size[v];
    		if(size[son[u]] < size[v])
    			son[u] = v;
    	}
    }
    
    inline void dfs2(int u, int t)
    {
    	top[u] = t;
    	if(son[u])
    		dfs2(son[u], t);
    	for(int i = ver[u]; i; i = e[i].nxt)
    	{
    		int v = e[i].v;
    		if(v == fa[u] || v == son[u])
    			continue;
    		dfs2(v, v);
    	}
    }
    
    inline int lca(int u, int v)
    {
    	while(top[u] != top[v])
    	{
    		if(dep[top[u]] < dep[top[v]])
    			swap(u, v);
    		u = fa[top[u]];
    	}
    	return dep[u] < dep[v] ? u : v;
    }
    
    inline bool check(int k)
    {
    	memset(f, 0, sizeof f);
    	int cnt = 0;
    	for(int i = 1; i <= m; i++)
    	{
    		if(d[i] <= k)
    			continue;
    		f[a[i]]++, f[b[i]]++, f[c[i]] -= 2;
    		cnt++;
    	}
    	for(int i = n; i >= 1; i--)
    	{
    		f[fa[s[i]]] += f[s[i]];
    		if(w[s[i]] >= maxw - k && f[s[i]] == cnt)
    			return true;
    	}
    	return false;
    }
    
    inline int read()
    {
    	static int x;
    	static char c;
    	x = 0, c = getchar();
    	while(!isdigit(c))
    		c = getchar();
    	while(isdigit(c))
    		x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    	return x;
    }
    
    int main()
    {
    	n = read(), m = read();
    	for(int i = 1; i < n; i++)
    	{
    		int u = read(), v = read(), w = read();
    		adde(u, v, w);
    		adde(v, u, w);
    		l = max(l, w);
    	}
    	dep[1] = 1;
    	dfs1(1, 0);
    	dfs2(1, 1);
    	for(int i = 1; i <= m; i++)
    	{
    		a[i] = read(), b[i] = read();
    		c[i] = lca(a[i], b[i]);
    		d[i] = dis[a[i]] + dis[b[i]] - (dis[c[i]] << 1);
    		r = max(r, d[i]);
    	}
    	maxw = r, l = maxw - l, r++;
    	while(l <= r)
    	{
    		mid = (l + r) >> 1;
    		if(check(mid))
    			ans = mid, r = mid - 1;
    		else
    			l = mid + 1;
    	}
    	printf("%d", ans);
    	return 0;
    }
    
    
    
    • 2
      @ 2023-7-24 17:33:08

      image image
      image

      #include <bits/stdc++.h>
      #define ll long long
      #define mod 1000000007
      using namespace std;
      const int N=300005;
      struct node{
      	int y,next,cost;
      }b[N*2];
      struct node1{
      	int x,y,cost,lca;
      	bool operator<(const node1 &k)const{
      		return cost>k.cost;
      	}
      }a[N];
      int n,m,k,s,t,head[N],tot,f[N][20],d[N],de[N],log2n,v[N];
      int l,r,tp[N],tmp;
      void add(int s,int t,int k){
      	b[++tot].next=head[s];
      	head[s]=tot;
      	b[tot].y=t;
      	b[tot].cost=k;
      }
      void dfs(int x,int fa){
      	tp[++tmp]=x;
      	for (int k=head[x];k;k=b[k].next){
      		int y=b[k].y;
      		if (y!=fa){
      			d[y]=d[x]+b[k].cost;
      			f[y][0]=x;
      			de[y]=de[x]+1;
      			v[y]=b[k].cost;
      			dfs(y,x);
      		}
      	}
      }
      int lca(int s,int t){
      	if (de[s]<de[t]) swap(s,t);
      	int k=de[s]-de[t],o=0;
      	while (k){
      		if (k&1) s=f[s][o];
      		k>>=1;++o;
      	}
      	if (s==t) return s;
      	for (int j=log2n;j>=0;--j)
      		if (f[s][j]!=f[t][j]){
      			s=f[s][j];
      			t=f[t][j];
      		}
      	return f[s][0];
      }
      int check(int mid){
      	memset(d,0,sizeof(d));
      	int sum=0;
      	for (int i=1;i<=m;++i){
      		if (a[i].cost>mid){//差分 
      			++sum;
      			d[a[i].x]++;
      			d[a[i].y]++;
      			d[a[i].lca]-=2;
      		}
      		else break;
      	}
      	for (int i=n;i>=1;--i)//求出每条边的权值 
      		for (int k=head[tp[i]];k;k=b[k].next){
      			int y=b[k].y;
      			if (y!=f[tp[i]][0]) d[tp[i]]+=d[y];
      		}	
      	int mx=0;
      	for (int i=2;i<=n;++i)
      		if (d[i]==sum){//权值等于路径条数取边权最大值 
      			mx=max(mx,v[i]);
      		}
      	if (mx>=a[1].cost-mid) return 1;
      	else return 0;
      }
      int main(){
      	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
      	cin>>n>>m;
      	for (int i=1;i<n;++i){
      		cin>>s>>t>>k;
      		add(s,t,k);
      		add(t,s,k);
      	}
      	de[1]=1;
      	dfs(1,0);
      	log2n=log2(n);
      	for (int j=1;j<=log2n;++j)
      		for (int i=1;i<=n;++i)
      			f[i][j]=f[f[i][j-1]][j-1];
      	for (int i=1;i<=m;++i){
      		cin>>a[i].x>>a[i].y;
      		a[i].lca=lca(a[i].x,a[i].y);//提前求lca 
      		a[i].cost=d[a[i].x]+d[a[i].y]-2*d[a[i].lca];
      	}
      	sort(a+1,a+1+m);//按照边权从大到小排序 
      	l=0;r=0x3f3f3f3f;
      	while (l<=r){//二分答案 
      		int mid=(l+r)>>1;
      		if (check(mid)) r=mid-1;
      		else l=mid+1;
      	}
      	cout<<l<<endl;
      }
      
      • 1

      信息

      ID
      336
      时间
      1000ms
      内存
      256MiB
      难度
      5
      标签
      递交数
      63
      已通过
      25
      上传者