【bzoj2753】[SCOI2012]滑雪与时间胶囊

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;

typedef long long LL;

#define N 1000010

struct edge
{
    LL to,next;
}e[N<<1];
LL head[N<<1];
LL cnt;

struct Node
{
    LL x,y,z;
}a[N<<1];

LL n,m;
LL x,y,z;
LL tot,ans;

LL fa[N],vis[N],q[N];

LL h[N];

int find(LL x)
{
    return fa[x]==x ? x : fa[x]=find(fa[x]);
}

void link(LL x,LL y,LL z)
{
    e[++cnt]=(edge){y,head[x]};
    head[x]=cnt;
    a[cnt]=(Node){x,y,z};
}

int cmp(Node x,Node y)
{
    return h[x.y]>h[y.y] || (h[x.y]==h[y.y] && x.z<y.z);
}

void bfs()
{
    queue<LL>q;
    q.push(1);
    vis[1]=1;
    while (!q.empty())
    {
        LL now=q.front();
        q.pop();
        for (LL i=head[now];i;i=e[i].next)
        {
            LL t=e[i].to;
            if (!vis[t])
            {
                q.push(t);
                vis[t]=1;
                tot++;
            }
        }
    }
}

int main()
{
    scanf("%lld%lld",&n,&m);
    for (LL i=1;i<=n;i++)
        scanf("%lld",&h[i]);
    for (LL i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        if (h[x]>=h[y])
            link(x,y,z);
        if (h[x]<=h[y])
            link(y,x,z);
    }
    bfs();
    printf("%lld ",tot+1);
    for (LL i=1;i<=n;i++)
        fa[i]=i;
    sort(a+1,a+cnt+1,cmp);
    for (LL i=1;i<=cnt;i++)
    {
        x=a[i].x;
        y=a[i].y;
        if (!vis[x] || !vis[y])
            continue;
        LL r1=find(x),r2=find(y);
        if (r1!=r2)
            fa[r1]=r2,ans+=a[i].z;
    }
    printf("%lld\n",ans);
    return 0;
}

  

#include<algorithm>

#include<iostream>

#include<cstdlib>

#include<cstring>

#include<cstdio>

#include<cmath>

#include<queue>

using namespace std;

typedef long long LL;

#define N 1000010

struct edge

{

    LL to,next;

}e[N<<1];

LL head[N<<1];

LL cnt;

struct Node

{

    LL x,y,z;

}a[N<<1];

LL n,m;

LL x,y,z;

LL tot,ans;

LL fa[N],vis[N],q[N];

LL h[N];

int find(LL x)

{

    return fa[x]==x ? x : fa[x]=find(fa[x]);

}

void link(LL x,LL y,LL z)

{

    e[++cnt]=(edge){y,head[x]};

    head[x]=cnt;

    a[cnt]=(Node){x,y,z};

}

int cmp(Node x,Node y)

{

    return h[x.y]>h[y.y] || (h[x.y]==h[y.y] && x.z<y.z);

}

void bfs()

{

    queue<LL>q;

    q.push(1);

    vis[1]=1;

    while (!q.empty())

    {

        LL now=q.front();

        q.pop();

        for (LL i=head[now];i;i=e[i].next)

        {

            LL t=e[i].to;

            if (!vis[t])

            {

                q.push(t);

                vis[t]=1;

                tot++;

            }

        }

    }

}

int main()

{

    scanf("%lld%lld",&n,&m);

    for (LL i=1;i<=n;i++)

        scanf("%lld",&h[i]);

    for (LL i=1;i<=m;i++)

    {

        scanf("%lld%lld%lld",&x,&y,&z);

        if (h[x]>=h[y])

            link(x,y,z);

        if (h[x]<=h[y])

            link(y,x,z);

    }

    bfs();

    printf("%lld ",tot+1);

    for (LL i=1;i<=n;i++)

        fa[i]=i;

    sort(a+1,a+cnt+1,cmp);

    for (LL i=1;i<=cnt;i++)

    {

        x=a[i].x;

        y=a[i].y;

        if (!vis[x] || !vis[y])

            continue;

        LL r1=find(x),r2=find(y);

        if (r1!=r2)

            fa[r1]=r2,ans+=a[i].z;

    }

    printf("%lld\n",ans);

    return 0;

}

时间: 2024-09-29 02:01:29

【bzoj2753】[SCOI2012]滑雪与时间胶囊的相关文章

bzoj2753[SCOI2012]滑雪与时间胶囊 最小生成树

Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2843  Solved: 993[Submit][Status][Discuss] Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi.a180285能从景点i 滑到景点j 当且仅当存在一条i 和j 之间的边,且i 的高度不小于j. 与其他滑雪爱好者不同,a180

[BZOJ2753][SCOI2012]滑雪与时间胶囊(特殊的有向树形图)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2753 分析: 第一问:直接BFS扩展知道无法扩展 第二问: 看似就是最小树形图啊= =但是数据范围太大了……猪牛算法是O(mn),肯定TLE的. 于是考虑一下用最小生成树的想法 当然单纯的用Kruskal,是不可以的,问题处在哪里呢?因为如果按边权排序从小到大那么边的方向不确定,故最后形成的图中可能有边的方向反了导致不是一个树形图. 所以可以想到边的终点的点对应的高度大小肯定优先于边

bzoj2753: [SCOI2012]滑雪与时间胶囊

bfs+最小树形图+kruskal算法. 最小树形图形象地来说就是有向图的最小生成树,这个不能拿kruskal算法或者是prim算法直接求,否则会错. 就是w[u][v]!=w[v][u]的情况. 而这道题用朱刘算法肯定是行不通的. 但是这道题的有向边并不是边的性质,而是点的高度决定的.这样我们就可以分层求最小生成树. 如果加进高度为h的点,只需用kruskal算法选最短的边就可以了,而且不会影响到后面的选择. 于是我们把kruskal算法的排序改成以结尾点高度为第一关键字降序和边长度为第二关键

【SCOI2012】【BZOJ2753】滑雪与时间胶囊

2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MB Submit: 1524 Solved: 536 [Submit][Status][Discuss] Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi.a180285能从景点i 滑到景点j 当且仅当存在一条i 和j 之间的边,且i

[SCOI2012]滑雪与时间胶囊

2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2362  Solved: 821[Submit][Status][Discuss] Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi.a180285能从景点i 滑到景点j 当且仅当存在一条i 和j 之间的边,且i

2753: [SCOI2012]滑雪与时间胶囊

2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2633  Solved: 910 Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi.a180285能从景点i 滑到景点j 当且仅当存在一条i 和j 之间的边,且i 的高度不小于j. 与其他滑雪爱好者不同,a1802

[BZOJ 2753][SCOI2012]滑雪与时间胶囊

Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi.a180285能从景点i 滑到景点j 当且仅当存在一条i 和j 之间的边,且i 的高度不小于j. 与其他滑雪爱好者不同,a180285喜欢用最短的滑行路径去访问尽量多的景点.如果仅仅访问一条路径上的景点,他会觉得数量太少.于是a180285拿出了他随身携带的时间胶囊.这是一种很神奇的药物,吃下之后可以立即回到

bzoj 2753: [SCOI2012] 滑雪与时间胶囊 Label:MST

题目描述 a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi.a180285能从景点i 滑到景点j 当且仅当存在一条i 和j 之间的边,且i 的高度不小于j. 与其他滑雪爱好者不同,a180285喜欢用最短的滑行路径去访问尽量多的景点.如果仅仅访问一条路径上的景点,他会觉得数量太少.于是a180285拿出了他随身携带的时间胶囊.这是一种很神奇的药物,吃下之后可以立即回到上个经过的景点

【BZOJ】【2753】【SCOI2012】滑雪与时间胶囊

Kruskal/最小树形图 然而蒟蒻并不会做这题>_> 本来以为是有向图最小生成树,即最小树形图,但这数据范围有点…… 膜拜了zyf的题解:http://www.cnblogs.com/zyfzyf/p/4004236.html 题解:(摘自声亦香) 因为只能从高处到低处,所以无向边可以当有向边看待,然后按照题目意思就是给你一个有向图,求一个最小树形图,然后如果你用朱刘算法来算,就只能得到70分. 这道题具有与其余最小树形图不一样的地方:点有高度!难道高度只是拿来转化为有向边吗?当然不是. 回