zoukankan      html  css  js  c++  java
  • SDOI 2017 天才黑客

    这题为了不写线段树优化连边写单log的前缀后缀连边调死我了。。。。。

    码力榨干,题解咕咕咕

    #include "iostream"
    #include "algorithm"
    #include "cstring"
    #include "cstdio"
    #include "vector"
    #include "queue"
    using namespace std;
    #define mem(a) memset( a , 0 , sizeof a)
    #define MAXN 1000006
    #define pii pair<int,int>
    #define pli pair<long long,int>
    #define se second
    #define fi first
    #define mp make_pair
    int n , m , k;
    vector<pii> adj[MAXN];
    int pos[MAXN];
    int head[MAXN] , to[MAXN] , nex[MAXN] , wto[MAXN] , ecn;
    void ade( int u , int v , int w ) {
    //    printf("%d %d %d
    ",u,v,w);
        to[++ ecn] = v , nex[ecn] = head[u] , head[u] = ecn , wto[ecn] = w;
    }
    vector<int> G[MAXN];
    int cnt;
    int dfn[MAXN] , cl , dep[MAXN] , g[MAXN][18];
    void dfs( int u , int fa ) {
        dfn[u] = ++ cl;
        for( int i = 0 ; i < G[u].size() ; ++ i ) {
            int v = G[u][i];
            if( v == fa ) continue;
            dep[v] = dep[u] + 1;
            g[v][0] = u;
            for( int k = 1 ; k < 18 ; ++ k )
                if( g[g[v][k-1]][k-1] ) g[v][k] = g[g[v][k-1]][k-1];
                else break;
            dfs( v , u );
        }
    }
    int lca( int u , int v ) {
        if( dep[u] < dep[v] ) swap( u , v );
        for( int k = 17 ; k >= 0 ; -- k ) if( dep[g[u][k]] >= dep[v] ) u = g[u][k];
        if( u == v ) return dep[u];
        for( int k = 17 ; k >= 0 ; -- k ) if( g[u][k] != g[v][k] ) u = g[u][k] , v = g[v][k];
        return dep[g[u][0]];
    }
    bool cmp( pii a , pii b ) {
        return dfn[pos[a.fi]] < dfn[pos[b.fi]];
    }
    int bac[MAXN];
    priority_queue<pli> Q;
    long long dis[MAXN]; int vis[MAXN];
    void dijk( int s ) {
        memset( dis , 0x3f3f , sizeof dis );
        memset( vis , 0 , sizeof vis );
        while( !Q.empty( ) ) Q.pop();
        dis[s] = 0 , Q.push( mp( 0 , s ) );
        while( !Q.empty() ) {
            int u = Q.top().se; Q.pop();
            if( vis[u] ) continue;
            vis[u] = 1;
            for( int i = head[u] ; i ; i = nex[i] ) {
                int v = to[i];
                if( dis[v] > dis[u] + wto[i] && !vis[v] )
                    dis[v] = dis[u] + wto[i] , Q.push( mp( -dis[v] , v ) );
            }
        }
    }
    long long ans[MAXN];
    int main() {
    //    freopen("q.in","r",stdin);
        int T;cin >> T;
        while( T-- ) {
            mem(head),mem(g),mem(dfn),mem(bac);
            cnt = cl = ecn = 0;
            cin >> n >> m >> k;
            for( int i = 1 ; i <= n ; ++ i ) adj[i].clear();
            for( int i = 1 ; i <= k ; ++ i ) G[i].clear();
            cnt = ( m << 1 ) + 2;
            for( int i = 1 , a , b , c , d ; i <= m ; ++ i ) {
                scanf("%d%d%d%d", &a, &b, &c, &d);
                adj[a].push_back(mp(i, 0)), adj[b].push_back(mp(i, 1)); // 0 : in , 1 : out
                pos[i] = d;
                ade(i << 1, i << 1 | 1, c);
                if( a == 1 ) ade( cnt , i << 1 , 0 );
                bac[i] = b;
            }
            for( int i = 1 , u , v ; i < k ; ++ i )
                scanf("%d%d%*d",&u,&v) , G[u].push_back( v );
            dfs( 1 , 1 );
            for( int i = 1 ; i <= n ; ++ i ) {
                sort( adj[i].begin() , adj[i].end() , cmp );
                int sz = adj[i].size();
                if( sz <= 1 ) continue;
                vector<int> w; w.push_back( 0 );
                for( int j = 1 ; j < sz ; ++ j )
                    w.push_back( lca( pos[adj[i][j - 1].fi] , pos[adj[i][j].fi] ) );
                int prein , preout;
                if( adj[i][0].se ) {
                    ade( adj[i][0].fi << 1 | 1 , ++ cnt , 0 ) , preout = cnt;
                    prein = ++ cnt;
                } else {
                    ade( ++ cnt , adj[i][0].fi << 1 , 0 ) , prein = cnt;
                    preout = ++ cnt;
                }
                for( int j = 1 ; j < sz ; ++ j ) {
                    if( adj[i][j].se ) {
                        ade( adj[i][j].fi << 1 | 1 , ++ cnt , 0 ) , ade( preout , cnt , 0 );
                        ade( preout , cnt + 1 , w[j] ) , preout = cnt;
                        ade( prein , ++ cnt , 0 ) , prein = cnt;
                    } else {
                        ade( ++ cnt , adj[i][j].fi << 1 , 0 ) , ade( prein , cnt , 0 );
                        ade( preout , cnt , w[j] ) , prein = cnt;
                        ade( preout , ++ cnt , 0 ) , preout = cnt;
                    }
                }
                // reversed ...
                if( adj[i][sz - 1].se ) {
                    ade( adj[i][sz - 1].fi << 1 | 1 , ++ cnt , 0 ) , preout = cnt;
                    prein = ++ cnt;
                } else {
                    ade( ++ cnt , adj[i][sz - 1].fi << 1 , 0 ) , prein = cnt;
                    preout = ++ cnt;
                }
                for( int j = sz - 2 ; j >= 0 ; -- j ) {
                    if( adj[i][j].se ) {
                        ade( adj[i][j].fi << 1 | 1 , ++ cnt , 0 ) , ade( preout , cnt , 0 );
                        ade( preout , cnt + 1 , w[j + 1] ) , preout = cnt;
                        ade( prein , ++ cnt , 0 ) , prein = cnt;
                    } else {
                        ade( ++ cnt , adj[i][j].fi << 1 , 0 ) , ade( prein , cnt , 0 );
                        ade( preout , cnt , w[j + 1] ) , prein = cnt;
                        ade( preout , ++ cnt , 0 ) , preout = cnt;
                    }
                }
            }
            dijk( ( m << 1 ) + 2 );
            memset( ans , 0x3f3f , sizeof ans );
            for( int i = 1 ; i <= m ; ++ i )
                ans[bac[i]] = min( ans[bac[i]] , dis[i << 1 | 1] );
            for( int i = 2 ; i <= n ; ++ i ) printf("%lld
    ",ans[i]);
    //        puts("");
        }
    }
    
  • 相关阅读:
    了解HDD或SDD磁盘的健康状态
    修复丢失的打开方式
    Invoke-WebRequest : 请求被中止: 未能创建 SSL/TLS 安全通道。
    绕过禁止未登陆用户访问
    debug
    更新已有数据
    编码格式(乱码)
    ajax
    Http
    科学的管理和规范标准
  • 原文地址:https://www.cnblogs.com/yijan/p/bzoj4912.html
Copyright © 2011-2022 走看看