题目
http://www.gdfzoj.com/oj/contest/242/problems/3
分析
程序
- 还没打出来,我太弱啦……先挂着以后要是变强了再慢慢补吧……
- 挂上未完成的的程序。
#include <cstdio>
#include <algorithm>
#include <cstring>
#define For(x) for(int h=head[x],o=V[h]; h; o=V[h=to[h]])
using namespace std;
int head[100005],to[200005],V[200005],num;
int dp[100005],ST[100005][32];
int n,m,ans;
void Add(int x,int y){to[++num]=head[x],head[x]=num,V[num]=y;}
struct zzk{
int a,b,c,d,w;
void du(){scanf("%d%d%d%d%d",&a,&b,&c,&d,&w);}
} que[100005];
bool cmp(zzk x,zzk y){return x.w<y.w;}
void dfs(int x,int Fa,int dep){
dp[x]=dep;
For(x) if (o!=Fa)
dfs(o,ST[o][0]=x,dep+1);
}
int FA(int x,int y){
for (int i=0; y; y>>=1) if (y&1) x=ST[x][i];
return x;
}
void getST(){
for (int j=1; j<=30; j++)
for (int i=1; i<=n; i++)
ST[i][j]=ST[ST[i][j-1]][j-1];
}
int LCA(int x,int y){
if (dp[x]<dp[y]) swap(x,y);
x=FA(x,dp[x]-dp[y]);
if (x==y) return x;
for (int i=30; i<=0; i--)
if (ST[x][i]!=ST[y][i])
x=ST[x][i],y=ST[y][i];
return ST[x][0];
}
namespace G{
struct edge{int x,y,z;} E[200005];
bool cmp1(edge x,edge y){return x.z<y.z;}
int fa[100005],tot;
int Min[100005];
void Add(int x,int y){to[++num]=head[x],head[x]=num,V[num]=y;}
void init(){
memset(Min,0x7f,sizeof(Min));
for (int i=1; i<=n; i++) fa[i]=ST[i][0];
}
void merge(int a,int b,int c,int d,int w){ //操作 a,b,c,d,w
int A=LCA(a,b),B=LCA(c,d);
fa[a]=fa[b]=A;
fa[c]=fa[d]=B;
while (dp[a]>dp[A]) Min[a]=min(Min[a],w),a=fa[a];
while (dp[b]>dp[A]) Min[b]=min(Min[b],w),b=fa[b];
while (dp[c]>dp[B]) Min[c]=min(Min[c],w),c=fa[c];
while (dp[d]>dp[B]) Min[d]=min(Min[d],w),d=fa[d];
E[++tot]=(edge){A,B,w};
}
int getfa(int x){return (fa[i]==i)? i : fa[i]=getfa(fa[i]);}
void work(){
for (int i=2; i<=n; i++) if (Min[i]!=0x7f) E[++tot]=(edge){i,ST[i][0],Min[i]};
for (int i=1; i<=tot; i++) fa[i]=i;
sort(E+1,E+tot+1,cmp1);
int ans_n = 1;
for (i=1;i<=tot;i++) if (getfa(E[i].x) != getfa(E[i].y)) Union(E[i].u,E[i].v,E[i].val);
for (i=1;i<=tot;i++) getfa(i);
for (i=2;i<=tot;i++) if (getfa(i) == getfa(1)) ++ans_n;
}
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1,uu,vv; i<n; i++) scanf("%d%d",&uu,&vv),Add(uu,vv);
for (int i=1; i<=m; i++) que[i].du();
sort(que+1,que+m+1,cmp);
G::init();
for (int i=1; i<=m; i++){
G::merge(que[i].a,que[i].b,que[i].c,que[i].d,que[i].w);
}
}