2 条题解
-
2
#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
#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
- 上传者