【每日一题】滑雪与时间胶囊

[SCOI2012]滑雪与时间胶囊

http://www.nowcoder.com/questionTerminal/b21e6e9227974d3888cb4a3912f59a59

题意:

有n个点,然后有m条边,且你只能从权值高的点走到权值低的点;且你可以回到之前你曾经走过的点,然后问从1出发,最多可以遍历多少个点,且遍历最多点时最小距离是多少?

思路:

首先需要保证遍历的点最多,应该希望新加入的点高度越高越好,因为这样就不会漏掉一些本来可以遍历的点,然后再希望距离越小越好;做一遍prim,将点加入生成树时以高度降序,到生成树距离升序来取,且每到一个点的代价就是这个点到生成树中所有点集中的最短路

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 1e5+10,M = 2e6+10;
struct Edge{
    int to,w,nex;
}e[M];
int dist[N],H[N];
struct Node{
    int high,dist,id;
    bool operator < (const Node&b) const{
        if(high != b.high) return high < b.high;
        return dist > b.dist;
    }
};
int head[N],idx;
void add_edge(int u,int v,int w){
    e[idx].to = v;
    e[idx].w = w;
    e[idx].nex = head[u];
    head[u] = idx++;
}
void init(){
    memset(head,-1,sizeof(head));idx = 0;
} 
int n,m,cnt,intree[N];
ll ans;
void prim(){
    priority_queue<Node> q;
    memset(dist,0x3f,sizeof(dist));
    dist[1] = 0;
    q.push((Node){H[1],0,1});
    while(q.size()){
        int u = q.top().id;q.pop();
        if(intree[u]) continue;
        intree[u] = 1;cnt++,ans+=dist[u];
        for(int i = head[u];~i;i = e[i].nex){
            int v = e[i].to,w = e[i].w;
            if(intree[v]) continue;
            if(dist[v] > w){
                dist[v] = w;
                q.push((Node){H[v],dist[v],v});
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++) scanf("%d",H+i);
    init();
    for(int i = 0,u,v,w;i < m;i++){
        scanf("%d%d%d",&u,&v,&w);
        if(H[u] >= H[v]) add_edge(u,v,w);
        if(H[v] >= H[u]) add_edge(v,u,w);
    }
    prim();
    printf("%d %lld\n",cnt,ans);
    return 0;
}
全部评论

相关推荐

09-24 18:25
门头沟学院 Java
点赞 评论 收藏
分享
xiaolihuam...:当然还有一种情况是你多次一面挂,并且挂的原因都比较类似,例如每次都是算法题写不出来。面试官给你的评价大概率是算法能力有待加强,算法能力有待提高,基础知识掌握的不错,项目过关,但是coding要加强。短期内高强度面试并且每次都是因为同样的原因挂(这个你自己肯定很清楚),会形成刻板印象,因为你偶尔一次算法写不出来,面试官自己也能理解,因为他清楚的知道自己出去面试也不一定每一次面试算法都能写出来。但是连续几次他发现你的面屏里面都是算法有问题,他就认为这不是运气问题,而是能力问题,这种就是很客观的评价形成了刻白印象,所以你要保证自己。至少不能连续几次面试犯同样的错。算法这个东西比较难保证,但是有些东西是可以的,例如某一轮你挂的时候是因为数据库的索引,这个知识点答的不好,那你就要把数据库整体系统性的复习,下一轮面试你可以,项目打的不好,可以消息队列答的不好,但是绝对不可以数据库再答的不好了。当然事实上对于任何面试都应该这样查漏补缺,只是对于字节来说这个格外重要,有些面试官真的会问之前面试官问过的问题
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务