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\n",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\n",ans[i]);
//        puts("");
    }
}
posted @ 2020-02-10 19:48  yijan  阅读(112)  评论(0编辑  收藏  举报