【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
- 【HDU】5740 Glorious Brilliance【费用流】
- HDU5740 Glorious Brilliance
- 【HDU5740 2016 Multi-University Training Contest 2G】【二分图染色+费用流+路径输出】Glorious Brilliance 最少交换次数使得相邻点颜色
- Arrest HDU 费用流
- hdu 3667 费用流
- HDU 3376 费用流
- hdu 1853 费用流
- HDU 1533 费用流
- hdu 4862 费用流
- hdu 4406 费用流
- hdu 5045 费用流
- hdu 5045 费用流
- HDU 4067 费用流
- HDU 3435 费用流
- HDU 5520 (费用流)
- hdu 5045 费用流
- hdu 5988 费用流
- hdu 3667 (费用流,拆边)
- 压感断 容流通
- 怒斥互联网社交产品
- [李景山php]每天TP5-20161210|Config.php
- 【继承】----子父类成员变量--内存简单图解
- 靠
- 【HDU】5740 Glorious Brilliance【费用流】
- Ajax
- 欢迎使用CSDN-markdown编辑器
- 写在国庆之后
- Codeforces Round #375 (Div. 2) D. Lakes in Berland
- 插入排序
- 62.63.64.Unique Paths
- 文章标题
- 编程实现strlen函数