zoukankan      html  css  js  c++  java
  • $P2573 [SCOI2012]滑雪$

    (problem)

    这题就是 搜索 + 最小生成树?

    反正就是这样的

    1. 求从1开始能最到几个地方。
      2.最短长度 即最小生成树。
      我的做法是 先前向星存图 存好之后遍历 弄好第一个问 顺便处理好第二个问。
      可以搜索 遍历出来 能到几个点。 然后顺便重新存图 因为有些路径就在这时候显得一点没用了。

    然后跑(kruskal) 求最短距离? 没了。

    关于排序的话 有一点 要从高到低排 高度相同的 取最小(最小生成树)

    所以的话呢
    我们需要一个cmp

    bool cmp(E x , E y) { return h[x.v] == h[y.v] ? x.w < y.w : h[x.v] > h[y.v] ; }
    
    

    然而这样的话 就可以达到排序的目的 也就是保证拓展的点最多

    关于前向星存图 注意的是 高度相等需要建双向边。

    数组开两倍(大雾

    #include <bits/stdc++.h>
    using namespace std ;
    //#define int long long 
    
    typedef long long LL ;
    inline int rd() { int x = 0 ; int f = 1 ; register char c ;
    #define gc c = getchar()
        while(isspace(gc)) ;
        if(c == '-') f = -1 , gc ;
        while(x = (x<<1) + (x<<3) + (c&15) , isdigit(gc)) ;
        return x * f ;
    #undef gc
    }
    
    int n , m ;
    const int inf = INT_MAX >> 1 ;
    const int N = 100000 + 5 ;
    int h[N] ;
    const int M = 1000000 + 5 ;
    struct node { int to ; int val ; int nxt ; } Edge[M << 1] ;
    int cnt(0) ;
    int head[N] ;
    struct E { int u ; int v ; int w ; } edge[M << 1] ;
    bool cmp(E x , E y) { return h[x.v] == h[y.v] ? x.w < y.w : h[x.v] > h[y.v] ; }
    inline void Add(int u , int v , int w) {
    	Edge[++ cnt].to = v , Edge[cnt].val = w , Edge[cnt].nxt = head[u] ;
    	head[u] = cnt ; 
    }
    int fa[N] ;
    inline int find (int x) { return x == fa[x] ? x : fa[x] = find (fa[x]) ; } 
    inline void merge(int x , int y) { fa[x] = y ; }
    bool vis[N] ;
    int num(0) , sum(1) ;
    LL ans(0) ;
    inline void Dfs(int x) {
    	for(register int i = head[x] ; i ; i = Edge[i].nxt) {
    		edge[++ num].u = x ; edge[num].v = Edge[i].to ; edge[num].w = Edge[i].val ;
    		if(!vis[Edge[i].to]) vis[Edge[i].to] = 1 , ++ sum , Dfs(Edge[i].to) ;
    	}
    } 
    inline void kruskal() {
    	sort(edge + 1 , edge + num + 1 , cmp) ;
    	for(register int i=1;i<=num;i++) {
    		int fx = find(edge[i].u) , fy = find(edge[i].v) ;
    		if(fx == fy) continue ;
    		merge(fx , fy) ; ans += edge[i].w ;
    	}
    	return ;
    }
    signed main() {
    	n = rd() , m = rd() ;
    	for(register int i=1;i<=n;i++) fa[i] = i ;
    	for(register int i=1;i<=n;i++) h[i] = rd() ;
    	for(register int i=1;i<=m;i++) {
    		int u = rd() , v = rd() , w = rd() ;
    		if(h[u] >= h[v]) Add(u , v , w) ;
    		if(h[u] <= h[v]) Add(v , u , w) ;
    	}
    	vis[1] = 1 , Dfs(1) ;
    	kruskal() ;
    	cout << sum << ' ' << ans << endl ;
    	return 0 ;
    }
    
  • 相关阅读:
    CentOS7配置Tomcat8开机自动启动
    StackExchange.Redis 异步超时解决方案
    同一个tomcat部署多个项目导致启动失败
    吐血记录微信小程序授权获取Unionid及linux下使用bouncycastle解密用户数据 遇到的坑
    CentOS7设置ssh服务以及端口修改
    linux CentOS7安装与配置nginx1.18.0 并设置开机启动
    C语言函数指针用法
    Javascript优点和缺点
    VIM 单词大小写转换
    python base64编码实现
  • 原文地址:https://www.cnblogs.com/qf-breeze/p/10753653.html
Copyright © 2011-2022 走看看