感受到網路流的強大了……這道題目的關鍵在於:
前後顏色不變的,流入流出的次數相等;原本是黑色的最後變成了白色,流出比流入次數多1;原本是白色最後變成黑色,流入比流出次數多一。所以我們將每一點拆成3個點,分別代表流入點,原點與流出點。最開始為黑色的點與源點連流量為1,費用為0的邊,最後為黑色的點與匯點連流量為1,費用為0的邊。
#includeusingnamespace
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表示白色棋子。以...