zoukankan      html  css  js  c++  java
  • Run For Beer CF575G

    Run for beer

    CF 575G

    如果直接bfs分层贪心可以做,但是很毒瘤,具体可以参考Gavinzheng的提交

    考虑魔改dijkstra

    首先,每次拿权值最小的来松弛肯定没有问题,只是怎么表示路径长度

    由于边权很小,我们只需要拿 排名 * 10 + w 当权值就可以了。

    这里的“权值”是相对的权值,具体可以看代码。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<stack>
    using namespace std;
    //#define int long long
    #define MAXN 100016
    #define pb push_back
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define inf 0x3f3f3f3f
    #define cmx( a , b ) a = max( a , b )
    #define cmn( a , b ) a = min( a , b )
    int n , m;
    int head[MAXN] , to[MAXN << 1] , wto[MAXN << 1] , nex[MAXN << 1] , ecn;
    void ade( int u , int v , int w ) {
    	to[++ecn] = v , nex[ecn] = head[u] , wto[ecn] = w , head[u] = ecn;
    }
    int dis[MAXN] , len[MAXN] , pre[MAXN] , done[MAXN];
    priority_queue<pii , vector<pii> , greater<pii> > Q;
    queue<int> q;
    void dijk( int s ) {
    	memset( dis , 0x3f , sizeof dis );
    	memset( len , 0x3f , sizeof len );
    	memset( pre , -1 , sizeof pre );
    	dis[s] = 0 , len[s] = 1;
    	q.push( s );
    	while( !q.empty() ) {
    		int u = q.front(); q.pop( );
    		for( int i = head[u] ; ~i ; i = nex[i] ) {
    			int v = to[i];
    			Q.push( mp( 0 , u ) );
    			if( dis[v] && ! wto[i] )
    				q.push( v ) , dis[v] = 0 , pre[v] = ( i ^ 1 ) , len[v] = len[u] + 1;
    		}
    	}
    	int rnk = 0 , last = -1;
    	while( !Q.empty() ) {
    		pii too = Q.top( ); Q.pop( );
    		int u = too.se;
    		if( done[u] ) continue;
    		done[u] = true;
    		if( last != dis[u] ) last = dis[u] , ++ rnk;
    		for( int i = head[u] ; ~i ; i = nex[i] ) {
    			int v = to[i];
    			if( dis[v] > rnk * 10 + wto[i] ) {
    				dis[v] = rnk * 10 + wto[i];
    				pre[v] = ( i ^ 1 );	
    				len[v] = len[u] + 1;
    				Q.push( mp( dis[v] , v ) );
    			} else if( dis[v] == rnk * 10 + wto[i] && len[v] > len[u] + 1 ) {
    				pre[v] = ( i ^ 1 );
    				len[v] = len[u] + 1;
    				Q.push( mp( dis[v] , v ) );
    			}
    		}
    	}
    }
    int main() {
    	memset( head , -1 , sizeof head ) , ecn = -1;
    	cin >> n >> m;
    	for( int i = 1 , u , v , w ; i <= m ; ++ i ) {
    		scanf("%d%d%d",&u,&v,&w);
    		++ u , ++ v;
    		ade( u , v , w ) , ade( v , u , w );
    	}
    	dijk( n );
    	int c = 1;
    	stack<int> sss;
    	while( c != n ) 
    		sss.push( wto[pre[c]] ) , c = to[pre[c]];
    	while( !sss.empty() && sss.top() == 0 ) sss.pop();
    	if( sss.empty() ) printf("0");
    	else while( !sss.empty() ) printf("%d",sss.top()) , sss.pop();
    	puts("");
    	printf("%d
    " , len[1]);
    	c = 1;
    	printf("%d ",0);
    	while( c != n ) 
    		c = to[pre[c]] , printf("%d ",c - 1);
    }
    
  • 相关阅读:
    字符串最大最小表示法模板 ( 字典序最大最小 )
    Manacher模板( 线性求最长回文子串 )
    2017南宁网络赛 Problem J Minimum Distance in a Star Graph ( 模拟 )
    字符串截取模板 && POJ 3450、3080 ( 暴力枚举子串 && KMP匹配 )
    HDU 6153 A Secret ( KMP&&DP || 拓展KMP )
    51Nod 1277 字符串中的最大值 ( KMP && DP )
    HDU 4300 Clairewd's message ( 拓展KMP )
    拓展KMP以及模板
    KMP解决字符串最小循环节相关问题
    序列终结者 BZOJ 1251 Splay
  • 原文地址:https://www.cnblogs.com/yijan/p/cf575g.html
Copyright © 2011-2022 走看看