zoukankan      html  css  js  c++  java
  • COJ 0500 杨老师的路径规划(MST)最小生成树

    杨老师的路径规划(MST)
    难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
    试题描述

    为满足同学们需求,杨老师在实验楼4层新建了好多个计算机教室供同学们使用。可是这样的话,由于路径很长,杨老师发现越来越难亲自走到每一个机房看看同学们有没有在玩游戏了。请你现在帮杨老师设计一个程序,给你每个教室间的路径长,设计出一条路线使每两个教室间都能联通且总长度最小,你只需要输出这个最小值即可。(裸MST)

    输入
    测试用例的第1行给出教室数目N ( < 100 );随后的N(N-1)/2行对应教室间的距离,每行给出三个正整数,分别是两个教室的编号,以及此两教室间的距离(int范围)。为简单起见,教室从1到N编号。
    输出
    输出最小的路径总长度。
    输入示例
    3
    1 2 1
    1 3 2
    2 3 4
    输出示例
    3
    其他说明
    n<100

    动态的最小生成树LCT:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 #define CH for(int d=0;d<=1;d++) if(ch[d])
    10 using namespace std;
    11 const int maxn=100+10,maxm=5000+10,inf=-1u>>1;
    12 struct node{
    13     node*fa,*ch[2],*mx;int x;bool rev;
    14     node(){fa=ch[0]=ch[1]=NULL;mx=this;x=0;rev=false;}
    15     void revt(){swap(ch[0],ch[1]);rev^=1;return;}
    16     void update(){mx=this;CH{if(mx->x<ch[d]->mx->x)mx=ch[d]->mx;}return;}
    17     void down(){if(rev){CH{ch[d]->revt();}rev=false;}return;}
    18 }lct[maxn+maxm],*nodecnt;
    19 int parent(node*x,node*&y){return (y=x->fa)?y->ch[0]==x?0:y->ch[1]==x?1:-1:-1;}
    20 void rotate(node*x){
    21     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
    22     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
    23     y->fa=x;x->fa=z;x->ch[d1^1]=y;
    24     if(d2!=-1) z->ch[d2]=x;
    25     y->update();return;
    26 }
    27 void pushdown(node*x){
    28     static node*s[maxn];int top=0;
    29     for(node*y;;x=y){
    30         s[top++]=x;y=x->fa;
    31         if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
    32     } while(top--) s[top]->down();return;
    33 }
    34 node*splay(node*x){
    35     pushdown(x);node*y,*z;int d1,d2;
    36     while(true){
    37         if((d1=parent(x,y))<0) break;
    38         if((d2=parent(y,z))<0){rotate(x);break;}
    39         if(d1==d2) rotate(y),rotate(x);
    40         else rotate(x),rotate(x);
    41     } x->update();return x;
    42 }
    43 node*access(node*x){
    44     node*ret=NULL;
    45     for(;x;x=x->fa) splay(x)->ch[1]=ret,(ret=x)->update();
    46     return ret;
    47 }
    48 void makeroot(int x){access(x+lct)->revt();return;}
    49 void link(int x,int y){makeroot(x);splay(x+lct)->fa=lct+y;return;}
    50 void cut(int x,int y){
    51     makeroot(x);node*p=(access(y+lct),splay(y+lct));
    52     p->ch[0]=p->ch[0]->fa=NULL;p->update();return;
    53 }
    54 node*findtop(int x){
    55     node*t=(access(x+lct),splay(x+lct));while(t->ch[0]) t->down(),t=t->ch[0];return t;
    56 }
    57 node*query(int x,int y){
    58     makeroot(x);return access(y+lct)->mx;
    59 }
    60 int n,m;
    61 inline int read(){
    62     int x=0,sig=1;char ch=getchar();
    63     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    64     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    65     return x*=sig;
    66 }
    67 inline void write(int x){
    68     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    69     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    70     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    71 }
    72 int s[maxm],t[maxm];
    73 void init(){
    74     n=read();m=n*(n-1)>>1;int ans=0;nodecnt=lct+n+1;
    75     for(int i=1;i<=m;i++){
    76         s[i]=read();t[i]=read();node*q=nodecnt++;q->x=read();int k=q-lct;makeroot(k);
    77         if(findtop(s[i])!=findtop(t[i])){
    78             link(s[i],k);link(t[i],k);ans+=q->x;
    79         }else{
    80             node*p=query(s[i],t[i]);if(p->x<q->x) continue;
    81             ans+=q->x-p->x;int id=p-lct-n;
    82             cut(s[id],p-lct);cut(t[id],p-lct);
    83             link(s[i],k);link(t[i],k);
    84         }
    85     } write(ans);
    86     return;
    87 }
    88 void work(){
    89     return;
    90 }
    91 void print(){
    92     return;
    93 }
    94 int main(){init();work();print();return 0;}

    静态Kruskal:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const int maxn=100+10,maxm=5000+10;
    11 struct edge{int x,y,w;}e[maxm];
    12 bool cmp(edge a,edge b){return a.w<b.w;}
    13 inline int read(){
    14     int x=0,sig=1;char ch=getchar();
    15     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    16     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    17     return x*=sig;
    18 }
    19 inline void write(int x){
    20     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    21     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    22     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    23 }
    24 int n,m,fa[maxn];
    25 int findset(int x){return (fa[x]==x)?x:fa[x]=findset(fa[x]);}
    26 void init(){
    27     n=read();m=n*(n-1)>>1;
    28     for(int i=1;i<=n;i++) fa[i]=i;
    29     int x,y;
    30     for(int i=1;i<=m;i++){
    31         x=read();y=read();
    32         e[i]=(edge){x,y,read()};
    33     }
    34     sort(e+1,e+1+m,cmp);
    35     int ans=0,cnt=0;
    36     for(int i=1;i<=m;i++){
    37         int x=findset(e[i].x),y=findset(e[i].y);
    38         if(x!=y){
    39             fa[y]=x;ans+=e[i].w;
    40             if(++cnt==n-1) break;
    41         }
    42     } write(ans);
    43     return;
    44 }
    45 void work(){
    46     return;
    47 }
    48 void print(){
    49     return;
    50 }
    51 int main(){init();work();print();return 0;}
  • 相关阅读:
    Java基础(六)
    Java基础(五)
    Java基础(四)
    Java基础(三)
    Java变量,标识符,数据类,运算符,表达式,Scanner(二)
    Mybatis(二) SQL映射文件
    Mybatis(一) 入门
    Ubuntu 16.04安装docker详细步骤
    Ubuntu原生源
    运用 jenkins 让你的项目优雅的持续化集成
  • 原文地址:https://www.cnblogs.com/chxer/p/4593386.html
Copyright © 2011-2022 走看看