【HDU】5899 oasis in desert 【二分匹配】

題目鏈接:oasis in desert

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;
typedef pair < int , int > pii ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 505 ;
const int INF = 0x3f3f3f3f ;

vector < int > G[MAXN] , s1 , s2 , ans ;
int d[MAXN][MAXN] ;
int n , m , limit ;
int col[MAXN] ;
int vis[MAXN] ;
int Ly[MAXN] ;
int Time ;

int paint ( int u , int c ) {
    if ( col[u] && col[u] != c ) return 0 ;
    if ( col[u] ) return 1 ;
    col[u] = c ;
    if ( c == 1 ) s1.push_back ( u ) ;
    else s2.push_back ( u ) ;
    for ( int i = 0 ; i < G[u].size () ; ++ i ) {
        if ( !paint ( G[u][i] , 3 - c ) ) return 0;
    }
    return 1 ;
}

int dfs ( int u ) {
    for ( int i = 0 ; i < G[u].size () ; ++ i ) {
        int v = G[u][i] ;
        if ( vis[v] == Time ) continue ;
        vis[v] = Time ;
        if ( Ly[v] == -1 || dfs ( Ly[v] ) ) {
            Ly[v] = u ;
            return 1 ;
        }
    }
    return 0 ;
}

int match ( vector < int >& s ) {
    clr ( Ly , -1 ) ;
    clr ( vis , 0 ) ;
    Time = 0 ;
    int ans = 0 ;
    for ( int i = 0 ; i < s.size () ; ++ i ) {
        ++ Time ;
        ans += dfs ( s[i] ) ;
    }
    return ans == s.size () ;
}   

bool work () {
    for ( int i = 1 ; i <= n ; ++ i ) if ( !col[i] ) {
        s1.clear () ;
        s2.clear () ;
        if ( !paint ( i , 1 ) ) return 0 ;
        if ( s1.size () != s2.size () ) return 0 ;
        if ( !match ( s1 ) ) return 0 ;
        sort ( s1.begin () , s1.end () ) ;
        sort ( s2.begin () , s2.end () ) ;
        if ( s1 > s2 ) swap ( s1 , s2 ) ;
        for ( int j = 0 ; j < s1.size () ; ++ j ) {
            ans.push_back ( s1[j] ) ;
        }
    }
    return 1 ;
}

void solve () {
    ans.clear () ;
    scanf ( "%d%d%d" , &n , &m , &limit ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        G[i].clear () ;
        d[i][i] = col[i] = 0 ;
        for ( int j = i + 1 ; j <= n ; ++ j ) {
            d[j][i] = d[i][j] = INF ;
        }
    }
    for ( int i = 1 ; i <= m ; ++ i ) {
        int u , v , c ;
        scanf ( "%d%d%d" , &u , &v , &c ) ;
        d[u][v] = d[v][u] = c ;
    }
    for ( int k = 1 ; k <= n ; ++ k ) {
        for ( int i = 1 ; i <= n ; ++ i ) {
            for ( int j = 1 ; j <= n ; ++ j ) {
                d[i][j] = min ( d[i][j] , d[i][k] + d[k][j] ) ;
            }
        }
    }
    int cnt = 1 ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        if ( d[1][i] < INF ) ++ cnt ;
        for ( int j = i + 1 ; j <= n ; ++ j ) {
            if ( d[i][j] <= limit ) {
                G[i].push_back ( j ) , G[j].push_back ( i ) ;
            }
        }
    }
    if ( cnt < n || !work () ) printf ( "Impossible\n" ) ;
    else {
        sort ( ans.begin () , ans.end () ) ;
        printf ( "%d\n" , ans.size () ) ;
        for ( int i = 0 ; i < ans.size () ; ++ i ) {
            i && putchar ( ' ' ) ;
            printf ( "%d" , ans[i] ) ;
        }
        if ( ans.size () ) puts ( "" ) ;
    }
}

int main () {
    int T ;
    scanf ( "%d" , &T ) ;
    for ( int i = 1 ; i <= T ; ++ i ) {
        solve () ;
    }
    return 0 ;
}
發佈了718 篇原創文章 · 獲贊 37 · 訪問量 64萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章