P2573 [SCOI2012]滑雪

题目链接

在题中每个点都有一个限制条件,对于一个点,只能通向高度低于它的点,所以我们可以对题目中的所有点建有向图。然后可以从1开始通过bfs找到所有可以通向的点。

找到了这些点过后又怎么办呢?题目中说要使得经过最多景点数的点的边权值最小。所以我们能够在bfs的同时将这些能够到达的点都建一个新的图。然后从1开始在这个新图上跑;kruskal即可求出最小的权值。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
struct node{
    int nxt,to,val;
}edge[maxn*3];
int dis[maxn];
int head[maxn],cnt;
void add(int x,int y,int v){
    edge[++cnt].nxt=head[x];
    edge[cnt].to=y;
    edge[cnt].val=v;
    head[x]=cnt;
}
int n,m,x,y,v;
int h[maxn];
bool vis[maxn];
int sum;
queue<int> q;
struct node2{
    int x,y,val;
}tree[maxn*3];
int tot;
int fa[maxn];
int get(int x){
    if(x==fa[x]) return x;
    return fa[x]=get(fa[x]);
}
void bfs(){
    memset(vis,false,sizeof(vis));
    q.push(1);
    vis[1]=true;
    sum=1;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=head[u];i;i=edge[i].nxt){
            int v=edge[i].to;
            tree[++tot].x=u;
            tree[tot].y=v;
            tree[tot].val=edge[i].val;
            if(!vis[v]){
                vis[v]=true;
                sum++;
                q.push(v);
            }
        }
    }
}
bool cmp(node2 a,node2 b){
    if(h[a.y]!=h[b.y]) return h[a.y]>h[b.y];
    else return a.val<b.val;
}
long long all;
void kruskal(){
    int ans=0;
    sort(tree+1,tree+1+tot,cmp);
    for(int i=1;i<=tot;i++){
        int f1=get(tree[i].x);
        int f2=get(tree[i].y);
        if(f1!=f2){
            fa[f1]=f2;
            ans++;
            all+=tree[i].val;
            if(ans==sum-1) break;
        }
    }
    printf("%d %lld\n",sum,all);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=n;i++) scanf("%d",&h[i]);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&v);
        if(h[x]>=h[y]) add(x,y,v);
        if(h[x]<=h[y]) add(y,x,v);
    }
    bfs();
    kruskal();
    return 0;
} 

原文地址:https://www.cnblogs.com/LJB666/p/11623715.html

时间: 2024-10-24 14:06:37

P2573 [SCOI2012]滑雪的相关文章

洛谷 P2573 [SCOI2012]滑雪

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

【题解】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 inlin

[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拿出了他随身携带的时间胶囊.这是一种很神奇的药物,吃下之后可以立即回到上个经过的景点

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算法的排序改成以结尾点高度为第一关键字降序和边长度为第二关键