• 【题解】Luogu P2573 [SCOI2012] 滑雪 最小生成树


    并查集写错少find了导致一直MLE。。。

    dfs+kruskal

    因为时间胶囊无限,所以相当于回溯回祖先节点再向下dfs

    先dfs一遍看最多能滑多少点,能滑到的点连边

    用这些新的边跑最小生成树,排序的时候先按高度从大到小再按边权从小到大

    code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 const int maxn=1e5+5;
     5 #define int long long
     6 inline int read(){
     7     int x=0,f=1;char s=getchar();
     8     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     9     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    10     return f*x;
    11 }
    12 int n,m,h[maxn],sum=1,tot,ans;
    13 struct Edge{
    14     int u,v,w;
    15 }E[maxn*20];
    16 struct edge{
    17     int nxt,to,w;
    18 }e[maxn*20];
    19 int head[maxn],cnt,fa[maxn];
    20 bool vis[maxn];
    21 inline void add(int from,int to,int w){
    22     e[++cnt].to=to;e[cnt].w=w;e[cnt].nxt=head[from];head[from]=cnt;
    23 }
    24 void dfs(int x){
    25     for(int i=head[x];i;i=e[i].nxt){
    26         int to=e[i].to;
    27         E[++tot].u=x;E[tot].v=to;E[tot].w=e[i].w;
    28         if(!vis[to]){
    29             vis[to]=1;sum++;dfs(to);
    30         }
    31     }
    32 }
    33 bool cmp(Edge a,Edge b){
    34     return h[a.v]==h[b.v]?a.w<b.w:h[a.v]>h[b.v];
    35 }
    36 int find(int x){
    37     return x==fa[x]?x:fa[x]=find(fa[x]);
    38 }
    39 int main(){
    40     n=read();m=read();
    41     for(int i=1;i<=n;i++){
    42         h[i]=read();fa[i]=i;
    43     }
    44     for(int i=1;i<=m;i++){
    45         int u,v,w;
    46         u=read();v=read();w=read();
    47         if(h[u]==h[v]){
    48             add(u,v,w);add(v,u,w);
    49         }
    50         else if(h[u]>h[v])add(u,v,w);
    51         else add(v,u,w);
    52     }
    53     vis[1]=1;dfs(1);
    54     sort(E+1,E+1+tot,cmp);
    55     int k=0;
    56     for(int i=1;i<=tot;i++){
    57         int u=find(E[i].u),v=find(E[i].v);
    58         if(u!=v){
    59             fa[u]=v;
    60             ans+=E[i].w;k++;
    61         }
    62         if(k==sum-1)break;
    63     }
    64     printf("%lld %lld",sum,ans);
    65     return 0;
    66 }
    67 /*
    68  acquisition 得到
    69  adapt 适应
    70  adequate 足够的
    71 */
    72 }
    73 signed main(){
    74     gengyf::main();
    75     return 0;
    76 }
    View Code

    忽略后面的单词(雾

  • 相关阅读:
    结对编程——四则运算
    需求分析
    结对编程
    调查问卷的心得体会
    软件工程课初步目标
    软件工程课程建议
    结对编程--fault,error,failure
    结对编程--四则运算
    需求分析
    结对编程
  • 原文地址:https://www.cnblogs.com/gengyf/p/11739154.html
Copyright © 2020-2023  润新知