zoukankan      html  css  js  c++  java
  • [BeiJing2010组队][BZOJ 1977]次小生成树 Tree

    话说这个[BeiJing2010组队]是个什喵玩意?

    这是一道严格次小生成树,而次小生成树的做法是层出不穷的

    MATO IS NO.1 的博客里对两种算法都有很好的解释,值得拥有:  (果然除我以外,所有自称傻 X 的都是神犇喵~)

      http://www.cppblog.com/MatoNo1/archive/2011/05/29/147627.aspx

    MATO还讲了一个神级复杂度的次小生成树:  (请全部读完。如果被坑,后果自负)

      http://www.cppblog.com/MatoNo1/archive/2011/11/16/149812.html

    如果你可以打开人人网的话(你懂的喵~),这也是篇很好的博文:

      http://blog.renren.com/share/235365847/6633394303 

    该说的都在上面了,我就扔扔代码吧  (高能勿喷)

      1 #include <cstdio>
      2 #include <algorithm>
      3 typedef long long llint;
      4 const int inf=0x7FFFFFFF;
      5 const int sizeOfN=100001;
      6 const int sizeOfM=300003;
      7 
      8 namespace IOspace
      9 {
     10     inline int getint()
     11     {
     12         register int num=0;
     13         register char ch;
     14         do ch=getchar(); while (ch<'0' || ch>'9');
     15         do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
     16         return num;
     17     }
     18     inline void putint(llint num, char ch='
    ')
     19     {
     20         char stack[15];
     21         register int top=0;
     22         if (num==0) stack[top=1]='0';
     23         for ( ;num;num/=10) stack[++top]=num%10+'0';
     24         for ( ;top;top--) putchar(stack[top]);
     25         if (ch) putchar(ch);
     26     }
     27 }
     28 
     29 int N, M;
     30 
     31 struct node {int u, v, c;};
     32 node a[sizeOfM];
     33 bool b[sizeOfM];
     34 inline bool operator < (node i, node j)
     35     {return i.c<j.c;}
     36 
     37 struct edge {int point, dist; edge * next;};
     38 edge MEM[sizeOfM], * PORT=MEM;
     39 edge * E[sizeOfN];
     40 inline edge * newedge(int _point, int _dist, edge * _next)
     41     {edge * ret=PORT++; ret->point=_point; ret->dist=_dist; ret->next=_next; return ret;}
     42 inline void build(int u, int v, int c)
     43     {E[u]=newedge(v, c, E[u]); E[v]=newedge(u, c, E[v]);}
     44 
     45 int r[sizeOfN];
     46 int find(int x) {return r[x]==x?x:r[x]=find(r[x]);}
     47 
     48 int f[sizeOfN][20], l[2][sizeOfN][20], h[sizeOfN];
     49 bool vis[sizeOfN];
     50 int top, stack[sizeOfN]; edge * temp[sizeOfN];
     51 inline void search();
     52 
     53 inline int max(int x, int y) {return x>y?x:y;}
     54 inline int min(int x, int y) {return x<y?x:y;}
     55 inline void swap(int & x, int & y) {int t=x; x=y; y=t;}
     56 inline int lg(int x) {int i; for (i=0;x>1;i++) x>>=1; return i;}
     57 inline int lowbit(int x) {return x & -x;}
     58 inline int lca(int, int, int);
     59 inline llint kurskal();
     60 inline void prepare();
     61 inline int calc();
     62 
     63 int main()
     64 {
     65     llint ans=0;
     66 
     67     N=IOspace::getint(); M=IOspace::getint();
     68     for (int i=0;i<M;i++) a[i].u=IOspace::getint(), a[i].v=IOspace::getint(), a[i].c=IOspace::getint();
     69 
     70     ans=kurskal();
     71     prepare();
     72     ans+=calc();
     73 
     74     IOspace::putint(ans);
     75 
     76     return 0;
     77 }
     78 inline void search()
     79 {
     80     f[1][0]=0; h[1]=1;
     81     for (stack[++top]=1, temp[top]=E[1];top; )
     82     {
     83         int & u=stack[top]; edge *& i=temp[top];
     84         if (!vis[u]) vis[u]=1;
     85         for ( ;i;i=i->next) if (!vis[i->point])
     86         {
     87             f[i->point][0]=u; h[i->point]=h[u]+1;
     88             l[0][i->point][0]=i->dist; l[1][i->point][0]=-inf;
     89             stack[++top]=i->point; temp[top]=E[i->point];
     90             break;
     91         }
     92         if (i) continue;
     93         top--;
     94     }
     95 }
     96 inline llint kurskal()
     97 {
     98     llint ret=0;
     99     int tot=N-1;
    100 
    101     std::sort(a, a+M);
    102     for (int i=1;i<=N;i++) r[i]=i;
    103 
    104     for (int i=0;i<M;i++)
    105     {
    106         int u=find(a[i].u), v=find(a[i].v);
    107         if (u!=v)
    108         {
    109             build(a[i].u, a[i].v, a[i].c); ret+=a[i].c;
    110             b[i]=1;
    111             r[u]=v;
    112             if (!--tot) break;
    113         }
    114     }
    115 
    116     return ret;
    117 }
    118 inline void prepare()
    119 {
    120     search();
    121     for (int j=1;j<20;j++)
    122         for (int i=1;i<=N;i++) if (h[i]>=(1<<j))
    123         {
    124             f[i][j]=f[f[i][j-1]][j-1];
    125             l[0][i][j]=l[0][i][j-1]; l[1][i][j]=l[1][i][j-1];
    126             if (l[0][f[i][j-1]][j-1]>l[0][i][j]) l[1][i][j]=l[0][i][j], l[0][i][j]=l[0][f[i][j-1]][j-1];
    127             else if (l[0][f[i][j-1]][j-1]<l[0][i][j])
    128                 if (l[0][f[i][j-1]][j-1]>l[1][i][j]) l[1][i][j]=l[0][f[i][j-1]][j-1];
    129         }
    130 }
    131 inline int lca(int u, int v, int x)
    132 {
    133     int ret=-1, dis;
    134 
    135     if (h[u]<h[v]) swap(u, v);
    136     while (dis=h[u]-h[v])
    137     {
    138         int up=lg(lowbit(dis));
    139         ret=max(ret, l[l[0][u][up]==x][u][up]);
    140         u=f[u][up];
    141     }
    142     if (u==v) return ret;
    143 
    144     for (int i=19;i>=0;i--)
    145         if (f[u][i]!=f[v][i])
    146         {
    147             ret=max(ret, l[l[0][u][i]==x][u][i]);
    148             ret=max(ret, l[l[0][v][i]==x][v][i]);
    149             u=f[u][i]; v=f[v][i];
    150         }
    151     ret=max(ret, l[l[0][u][0]==x][u][0]);
    152     ret=max(ret, l[l[0][v][0]==x][v][0]);
    153 
    154     return ret;
    155 }
    156 inline int calc()
    157 {
    158     int ret=inf;
    159     for (int i=0;i<M;i++)
    160         if (!b[i])
    161             ret=min(ret, a[i].c-lca(a[i].u, a[i].v, a[i].c));
    162     return ret;
    163 }
    本傻装B系列

    写的比树套树还长,真是没脸见人了喵~

  • 相关阅读:
    C#(99):Queue<T>队列与Stack<T>堆栈
    C#(99):字典Dictionary<Tkey.TValue>与SortedList
    C#(99):列表:List<T>与HashSet和只读集合
    C#(99):C#数组Array
    C#(99):枚举类型与位域枚举Enum
    C#(99):结构类型:Struct
    C#(99):定义类成员(属性、方法、索引、运算符、事件)、接口实现
    C#(99):定义类、System.Object对象、构造函数与析构函数、抽象类与静态类
    SuperSocket.ClientEngine介绍
    C#(99):五、并行编程
  • 原文地址:https://www.cnblogs.com/dyllalala/p/3897946.html
Copyright © 2011-2022 走看看