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

    题目

    点这里看题目。

    分析

    首先第一问非常简单,可以直接 BFS 解决。

    考虑第二问,类似于生成树,可以暴力朱刘算法解决显然我们只需要对 BFS 中遇到的点和边进行生成树。这里的边需要保证有 (h_uge h_v)

    注意到这些点是必选的,因此我们只需要保证在生成树构建的过程中总有加入的边是合法的,就可以把边近似地看作无向边。

    因此可以直接对于每条边,按照终点高度优先从高到低、边权次之由低到高排序并进行 Kruskal 。

    由于可到的点必然可以按照高度分层,因此我们实际上是在分层进行 Kruskal ,所以每次每条边的起点必然已经被加入。

    小结:

    利用高度带来的层的性质,将有向边转化为无向边,从而可以进行 Kruskal 。

    代码

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    #define rep( i, a, b ) for( int (i) = (a) ; (i) <= (b) ; ++ (i) )
    #define per( i, a, b ) for( int (i) = (a) ; (i) >= (b) ; -- (i) )
    
    typedef long long LL;
    
    const int MAXN = 2e5 + 5, MAXM = 1e6 + 5;
    
    template<typename _T>
    void read( _T &x )
    {
    	x = 0; char s = getchar(); int f = 1;
    	while( s < '0' || '9' < s ) { f = 1; if( s == '-' ) f = -1; s = getchar(); }
    	while( '0' <= s && s <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ); s = getchar(); }
    	x *= f;
    }
    
    template<typename _T>
    void write( _T x )
    {
    	if( x < 0 ) putchar( '-' ), x = -x;
    	if( 9 < x ) write( x / 10 );
    	putchar( x % 10 + '0' );
    }
    
    template<typename _T>
    void swapp( _T &x, _T &y )
    {
    	_T t = x; x = y, y = t;
    }
    
    struct Edge
    {
    	int to, nxt;
    }Graph[MAXM];
    
    struct KruEdge
    {
    	int u, v, w, ed;
    	KruEdge() { u = v = w = 0; }
    	KruEdge( int U, int V, int W ) { u = U, v = V, w = W; }
    	bool operator < ( const KruEdge &b ) const { return ed == b.ed ? w < b.w : ed > b.ed; }
    }E[MAXM];
    
    int q[MAXN];
    
    int head[MAXN], fa[MAXN], H[MAXN];
    int N, M, K, cnt = 0;
    bool vis[MAXN];
    
    void MakeSet( const int siz ) { rep( i, 1, N ) fa[i] = i; }
    int FindSet( const int u ) { return fa[u] = ( fa[u] == u ? u : FindSet( fa[u] ) ); }
    
    bool UnionSet( int u, int v )
    {
    	u = FindSet( u ), v = FindSet( v );
    	if( u == v ) return false; fa[u] = v; return true;
    }
    
    void AddEdge( const int from, const int to )
    {
    	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
    	head[from] = cnt;
    }
    
    int main()
    {
    	read( N ), read( M );
    	rep( i, 1, N ) read( H[i] );
    	rep( i, 1, M ) 
    	{
    		read( E[i].u ), read( E[i].v ), read( E[i].w );
    		if( H[E[i].u] < H[E[i].v] ) continue;
    		AddEdge( E[i].u, E[i].v ), E[i].ed = H[E[i].v];
    	}
    	int h = 1, t = 0; vis[q[++ t] = 1] = true;
    	while( h <= t )
    	{
    		int u = q[h ++], v;
    		for( int i = head[u] ; i ; i = Graph[i].nxt )
    			if( ! vis[v = Graph[i].to] ) vis[q[++ t] = v] = true;
    	}
    	write( t ), putchar( ' ' ); LL ans = 0;
    	sort( E + 1, E + 1 + M ); MakeSet( N );
    	rep( i, 1, M ) 
    		if( H[E[i].u] >= H[E[i].v] )
    			if( vis[E[i].u] && vis[E[i].v] && UnionSet( E[i].u, E[i].v ) )
    				ans += E[i].w;
    	write( ans ), putchar( '
    ' );
    	return 0;
    }
    
  • 相关阅读:
    win7下配置JAVA环境变量
    使用PLSQL Developer和DbVisualizer、SQLDBx查询oracle数据库时出现乱码
    PL/SQL连接ORACLE失败,ORA-12154: TNS: could not resolve the connect identifier specified
    分布式计算开源框架Hadoop入门实践(三)
    分布式计算开源框架Hadoop入门实践(二)
    js使用WebSocket,java使用WebSocket
    springboot管理类,springboot注入类
    博客园点击弹出桃心的js样式、自动落雪花 、复制放进去即可实现
    jquery提交表单 提交form表单
    vue下拉列表
  • 原文地址:https://www.cnblogs.com/crashed/p/14267748.html
Copyright © 2011-2022 走看看