2 条题解
-
0

// Kruskal 重构树 O(MlogM+NlogN) #include<bits/stdc++.h> using namespace std; const int N=20005,M=50005; //重构树 点数=2N,边数=4N int idx,h[N],to[M],ne[M]; void add(int u,int v){ to[++idx]=v;ne[idx]=h[u];h[u]=idx; to[++idx]=u;ne[idx]=h[v];h[v]=idx; } int n,m,q,p,val[N]; //val新建点点权 struct E{int x,y,w;}e[M]; //原图边 int pa[N]; //并查集数组 int dep[N],fa[N][21]; //树上倍增数组 int find(int x){ //并查集查找 return pa[x]==x?x:pa[x]=find(pa[x]); } void kruskal(){ for(int i=1;i<=n;++i) pa[i]=i; sort(e+1,e+1+m,[&](E a,E b){return a.w>b.w;}); for(int i=1;i<=m;++i){ int x=find(e[i].x),y=find(e[i].y); if(x!=y){ val[++p]=e[i].w; //新建点点权=边权 pa[p]=pa[x]=pa[y]=p; //点x,y均指向点p add(p,x); add(p,y); //x,y均与p连无向边 } } } void dfs(int x,int f){ //预处理dep,fa数组 dep[x]=dep[f]+1; fa[x][0]=f; for(int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1]; for(int i=h[x];i;i=ne[i]){ int y=to[i]; if(y!=f) dfs(y,x); } } int lca(int x,int y){ //倍增求lca if(dep[x]<dep[y]) swap(x,y); //让x更深 for(int i=20;i>=0;i--)if(dep[fa[x][i]]>=dep[y]) x=fa[x][i]; //x向上跳到y的同一层 if(x==y) return x; for(int i=20;i>=0;i--)if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; //x,y一起向上跳 return fa[x][0]; } int main(){ ios::sync_with_stdio(0);cin.tie(0); cin>>n>>m; for(int i=1,u,v,w;i<=m;++i){ cin>>u>>v>>w; e[i]={u,v,w}; } cin>>q; p=n; //新建点编号初值 kruskal(); //重构森林 for(int i=1;i<=n;++i)if(!dep[i]){ //图可能是个森林 dfs(find(i),0); //预处理dep,fa数组 } for(int u,v;q--;){ cin>>u>>v; if(find(u)!=find(v)) printf("-1\n"); else printf("%d\n",val[lca(u,v)]); } } -
0
#include<bits/stdc++.h> //(只取部分有用的输入数据,使得图变成一棵树) using namespace std; struct edge{ int x,y,pre;}a[21100];int alen,last[11100]; void ins(int x,int y){alen++;a[alen]=edge{x,y,last[x]};last[x]=alen;} struct tnode{int f,dep,son,c,z,tp;}t[11100]; void dfs1(int x,int f) { t[x]={f,t[f].dep+1,0,1,0,0}; for(int k=last[x];k>0;k=a[k].pre) { int y=a[k].y; if(y!=f) { dfs1(y,f); t[x].c+=t[y].c; if(t[t[x].son].c<t[y].c) t[x].son=y; } } } int z, ys[11100]; void dfs2(int x,int tp) { ++z;t[x].z=z;t[x].tp=tp;ys[z]=x; if(t[x].son!=0) dfs2(t[x].son,tp); for(int k=last[x];k>0;k=a[k].pre) {int y=a[k].y; if(y!=t[x].f && y!=t[x].son) dfs2(y,y); } } struct trnode{int l,r,lc,rc,c;}tr[21100];int trlen; void bt(int l,int r) { trlen++;int now=trlen; tr[now]={l,r,-1,-1,0x3f3f3f3f}; if(l==r) tr[now].c=0x3f3f3f3f; else { int mid=(l+r)/2;tr[now].lc=trlen+1;bt(l,mid); tr[now].rc=trlen+1;bt(mid+1,r); tr[now].c=min(tr[tr[now].lc].c,tr[tr[now].rc].c); } } void change(int now,int x,int c) { if(tr[now].l==tr[now].r){ tr[now].c=c;return ;} int mid=(tr[now].l+tr[now].r)/2,lc=tr[now].lc,rc=tr[now].rc; if(x<=mid) change(lc,x,c); else change(rc,x,c); tr[now].c=min(tr[lc].c,tr[rc].c); } int findmin(int now,int l,int r) { if(tr[now].l==l && tr[now].r==r) return tr[now].c; int mid=(tr[now].l+tr[now].r)/2,lc=tr[now].lc,rc=tr[now].rc; if(r<=mid) return findmin(lc,l,r); else if(l>=mid+1) return findmin(rc,l,r); else return min(findmin(lc,l,mid),findmin(rc,mid+1,r)); } int solve(int x,int y) { int ans=0x3f3f3f3f; while(t[x].tp!=t[y].tp) { if(t[t[x].tp].dep>t[t[y].tp].dep)swap(x,y); ans=min(ans,findmin(1,t[t[y].tp].z,t[y].z)); y=t[t[y].tp].f; } if(x==y) return ans; if(t[x].dep>t[y].dep)swap(x,y); ans=min(ans,findmin(1,t[t[x].son].z,t[y].z)); return ans; } struct node{int x,y,c;}e[5100];bool v[51100]; bool cmp(node e1,node e2){ return e1.c>e2.c;} int fa[11100]; int findfa(int x){ return fa[x]=(fa[x]==x)?fa[x]:findfa(fa[x]);} int main() { int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].c); sort(e+1,e+m+1,cmp); for(int i=1;i<=n;i++)fa[i]=i; memset(v,0,sizeof(v));int s=0; for(int i=1;i<=m;i++) { int tx=findfa(e[i].x),ty=findfa(e[i].y); if(tx!=ty) { v[i]=1;fa[tx]=ty;s++;if(s==n-1)break; } } alen=0;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++)if(v[i]) ins(e[i].x,e[i].y),ins(e[i].y,e[i].x); t[0]={0,0,0,0,0,0}; dfs1(1,0); z=0; dfs2(1,1); trlen=0;bt(1,z); for(int i=1;i<=m;i++)if(v[i]) { if(t[e[i].x].dep>t[e[i].y].dep) swap(e[i].x,e[i].y); change(1,t[e[i].y].z,e[i].c); } int q;scanf("%d",&q); for(int i=1;i<=q;i++) { int x,y; scanf("%d%d",&x,&y);if(findfa(x)!=findfa(y)) printf("-1\n"); else printf("%d\n",solve(x,y)); } return 0; }
- 1
信息
- ID
- 361
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 93
- 已通过
- 40
- 上传者