題解 CQOI2012交換棋子

2022-02-27 14:04:16 字數 1340 閱讀 9718

感受到網路流的強大了……這道題目的關鍵在於:

前後顏色不變的,流入流出的次數相等;原本是黑色的最後變成了白色,流出比流入次數多1;原本是白色最後變成黑色,流入比流出次數多一。所以我們將每一點拆成3個點,分別代表流入點,原點與流出點。最開始為黑色的點與源點連流量為1,費用為0的邊,最後為黑色的點與匯點連流量為1,費用為0的邊。

#includeusing

namespace

std;

#define maxn 300

#define maxm 8000

#define inf 99999

intn, m, size, tem, a[maxn][maxn], b[maxn][maxn], c[maxn][maxn], head[maxm];

intcnp, fans, ans, cost, dis[maxm], pre[maxm], flow[maxm];

int dx[10] = ;

int dy[10] = ;

int s = 0

, t;

bool

vis[maxm];

deque

q;struct

edge

e[maxn * 400

];void add(int u, int v, int f, int

c)int get_id(int x, int

y)void

init()

intspfa()}}

}if(dis[t] >= inf) return

false

;

else

return

true;}

void

max_flow()

ans +=flow[t];

cost += flow[t] *dis[t];

}}void

get_input()

for(int i = 1; i <= n; i ++)

for(int i = 1; i <= n; i ++)

}void

connect()

else

if(b[i][j])

else

if(a[i][j])

for(int k = 1; k <= 8; k ++)

}}int

main()

max_flow();

if(ans == fans) printf("

%d", cost >> 1

);

else printf("

-1\n");

return0;

}

CQOI2012 交換棋子 費用流

有乙個n行m列的黑白棋盤,你每次可以交換兩個相鄰格仔 相鄰是指有公共邊或公共頂點 中的棋子,最終達到目標狀態。要求第i行第j列的格仔只能參與mi,j次交換。乙個點拆三份,入點,主點,出點 入點向主點連邊,主點向出點連邊,設該點允許的交換次數為 x 根據以下規則確定 s to 初態點,末態點 to t...

CQOI2012 交換棋子(拆點 費用流)

注意相鄰交換指的是八連通 顯然可以將黑白交換看做只有黑色棋子在空棋盤上移動 交換限制交給流量,那麼有代價自然就是費用流了 考慮直接將兩個相鄰格仔連起來,由於交換次數是相對單個格仔而言的,流量無法確定 既然交換次數是單個格仔的屬性,自然可以考慮到拆點來表示其屬性 考慮將乙個格仔拆成入點和出點,中間連一...

CQOI2012 交換棋子 網路流 費用流

有乙個n行 m列的黑白棋盤,你每次可以交換兩個相鄰格仔 相鄰是指有公共邊或公共頂點 中的棋子,最終達到目標狀態。要求第i行第j列的格仔只能參與mi j次交換。第一行包含兩個整數n,m 1 n,m 20 以下n 行為初始狀態,每行為乙個包含 m個字元的 01串,其中 0表示黑色棋子,1表示白色棋子。以...