【HDU】5740 Glorious Brilliance【费用流】

来源:互联网 发布:淘宝网妹儿粑粑饵料 编辑:程序博客网 时间:2024/05/21 04:16

题目链接:Glorious Brilliance

#include <bits/stdc++.h>using namespace std ;typedef long long LL ;#define clr( a , x ) memset ( a , x , sizeof a )const int MAXN = 505 ;const int MAXE = 2000005 ;const int INF = 0x3f3f3f3f ;struct Edge {    int v , c , w , n ;    Edge () {}    Edge ( int v , int c , int w , int n ) : v ( v ) , c ( c ) , w ( w ) , n ( n ) {}} ;Edge E[MAXE] ;int H[MAXN] , cntE ;int d[MAXN] , cur[MAXN] , vis[MAXN] ;int dp[MAXN][MAXN] , pre[MAXN][MAXN] ;int cost , flow ;int n , m ;int s , t ;vector < int > G[MAXN] , L , R ;vector < pair < int , int > > path , tmp , res ;int X[MAXN] , Y[MAXN] ;int c[MAXN] , val[MAXN] ;int S[MAXN] , top ;void init () {    cntE = 0 ;    clr ( H , -1 ) ;}void addedge ( int u , int v , int c , int w ) {    E[cntE] = Edge ( v , c , +w , H[u] ) ;    H[u] = cntE ++ ;    E[cntE] = Edge ( u , 0 , -w , H[v] ) ;    H[v] = cntE ++ ;}int spfa () {    queue < int > q ;    for ( int i = 0 ; i <= t ; ++ i ) {        d[i] = INF ;        vis[i] = 0 ;    }    d[s] = 0 ;    cur[s] = -1 ;    q.push ( s ) ;    while ( !q.empty () ) {        int u = q.front () ;        q.pop () ;        vis[u] = 0 ;        for ( int i = H[u] ; ~i ; i = E[i].n ) {            int v = E[i].v ;            if ( E[i].c && d[v] > d[u] + E[i].w ) {                d[v] = d[u] + E[i].w ;                cur[v] = i ;                if ( !vis[v] ) {                    vis[v] = 1 ;                    q.push ( v ) ;                }            }        }    }    if ( d[t] == INF ) return 0 ;    cost += d[t] ;    flow ++ ;    for ( int i = cur[t] ; ~i ; i = cur[E[i ^ 1].v] ) {        E[i].c -- ;        E[i ^ 1].c ++ ;    }    return 1 ;}int mcmf () {    cost = flow = 0 ;    while ( spfa () ) ;    return cost ;}int dfs ( int u ) {    if ( c[u] == 1 ) L.push_back ( u ) ;    else R.push_back ( u ) ;    for ( int i = 0 ; i < G[u].size () ; ++ i ) {        int v = G[u][i] ;        if ( !c[v] ) {            c[v] = 3 - c[u] ;            if ( !dfs ( v ) ) return 0 ;        }        if ( c[u] + c[v] != 3 ) return 0 ;    }    return 1 ;}void bfs ( int s ) {    queue < int > q ;    for ( int i = 1 ; i <= n ; ++ i ) {        dp[s][i] = INF ;    }    q.push ( s ) ;    pre[s][s] = 0 ;    dp[s][s] = 0 ;    while ( !q.empty () ) {        int u = q.front () ;        q.pop () ;        for ( int i = 0 ; i < G[u].size () ; ++ i ) {            int v = G[u][i] ;            if ( dp[s][v] == INF ) {                dp[s][v] = dp[s][u] + 1 ;                pre[s][v] = u ;                q.push ( v ) ;            }        }    }}void deal ( int x , int y , int& ans ) {    int cntx = 0 , cnty = 0 ;    for ( int i = 0 ; i < L.size () ; ++ i ) {        if ( val[L[i]] == x ) X[++ cntx] = L[i] ;    }    for ( int i = 0 ; i < R.size () ; ++ i ) {        if ( val[R[i]] == y ) Y[++ cnty] = R[i] ;    }    if ( cntx != cnty ) return ;    if ( !cntx && !cnty ) {        ans = 0 ;        tmp.clear () ;        return ;    }    if ( cntx == ( int ) L.size () && cnty == ( int ) R.size () ) {        ans = 0 ;        tmp.clear () ;        return ;    }    init () ;    s = 0 ;    t = cntx + cnty + 1 ;    for ( int i = 1 ; i <= cntx ; ++ i ) {        addedge ( s , i , 1 , 0 ) ;        for ( int j = 1 ; j <= cnty ; ++ j ) {            addedge ( i , j + cntx , 1 , dp[X[i]][Y[j]] ) ;        }    }    for ( int i = 1 ; i <= cnty ; ++ i ) {        addedge ( i + cntx , t , 1 , 0 ) ;    }    mcmf () ;    if ( cost < ans ) {        ans = cost ;        tmp.clear () ;        for ( int u = 1 ; u <= cntx ; ++ u ) {            for ( int i = H[u] ; ~i ; i = E[i].n ) {                int v = E[i].v ;                if ( v != s && E[i].c == 0 ) {                    tmp.push_back ( make_pair ( X[u] , Y[v - cntx] ) ) ;                    break ;                }            }        }    }}int flag = 0 ;void solve () {    path.clear () ;    scanf ( "%d%d" , &n , &m ) ;    for ( int i = 1 ; i <= n ; ++ i ) {        scanf ( "%1d" , &val[i] ) ;        G[i].clear () ;        c[i] = 0 ;    }    for ( int i = 1 ; i <= m ; ++ i ) {        int u , v ;        scanf ( "%d%d" , &u , &v ) ;        G[u].push_back ( v ) ;        G[v].push_back ( u ) ;    }    for ( int i = 1 ; i <= n ; ++ i ) {        bfs ( i ) ;    }    for ( int i = 1 ; i <= n ; ++ i ) if ( !c[i] ) {        c[i] = 1 ;        L.clear () ;        R.clear () ;        if ( !dfs ( i ) ) {            printf ( "-1\n" ) ;            return ;        }        int ans = INF ;        deal ( 0 , 1 , ans ) ;        deal ( 1 , 0 , ans ) ;        if ( ans == INF ) {            printf ( "-1\n" ) ;            return ;        }        for ( int i = 0 ; i < tmp.size () ; ++ i ) {            path.push_back ( tmp[i] ) ;        }    }    res.clear () ;    for ( int o = 0 ; o < path.size () ; ++ o ) {        int u = path[o].first , v = path[o].second ;        top = 0 ;        while ( v ) {            S[top ++] = v ;            v = pre[u][v] ;        }        for ( int i = 0 , j = 0 ; i < top ; ++ i ) {            if ( val[S[i]] != val[S[j]] ) {                for ( int k = i ; k > j ; -- k ) {                    res.push_back ( make_pair ( S[k] , S[k - 1] ) ) ;                }                swap ( val[S[i]] , val[S[j]] ) ;                j = i ;            }        }    }    printf ( "%d\n" , res.size () ) ;    for ( int i = 0 ; i < res.size () ; ++ i ) {        printf ( "%d %d\n" , res[i].first , res[i].second ) ;    }}int main () {    int T ;    scanf ( "%d" , &T ) ;    if ( T > 10 ) flag = 1 ;    while ( T -- ) solve () ;    return 0 ;}
0 0