GalaxyOJ-989 (思维+LCA+并查集)【还未打出……】

来源:互联网 发布:sql 字符串拼接 oracle 编辑:程序博客网 时间:2024/06/13 15:48

题目

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);    }}