time limit: 3 sec
memory limit: 128 mb
submit: 1136
solved: 423 [
submit][
status][
discuss]
有乙個n行m列的黑白棋盤,你每次可以交換兩個相鄰格仔(相鄰是指有公共邊或公共頂點)中的棋子,最終達到目標狀態。要求第i行第j列的格仔只能參與mi,j
次交換。
第一行包含兩個整數n,m(1<=n, m
<=20)。以下n行為初始狀態,每行為乙個包含m個字元的01串,其中0表示黑色棋子,1表示白色棋子。以下n行為目標狀態,格式同初始狀態。以下n行每行為乙個包含m個0~9數字的字串,表示每個格仔參與交換的次數上限。
輸出僅一行,為最小交換總次數。如果無解,輸出-1。
3 3110000
001000
110100
222222
2224 [
submit][
status][
discuss]
資料範圍非常網路流,答案非常費用流,不過不會建模。。
忽略圖中的白色棋子,只考慮黑色棋子,問題轉變成
將原圖中的每個黑色棋子移動成新圖的樣子,最少需要移動多少步
約束是每個格仔有乙個經過次數的上限
把某個黑棋子,從格仔a移動到格仔b,視作從a流出流入b
那麼就將乙個點i拆成三個點,xi,yi,zi,連(xi,yi)和(yi,zi)兩條邊
前者用來限制流入後者限制流出
分類討論圖中的每個點(i,j),記a = (xi,yi)的容量,b = (yi,zi)的容量,交換上限為wi,j
如果原圖和新圖中某個位置顏色相同,說明其流入流出次數應該相等,所以a = b = wi,j / 2
如果原圖是黑色而新圖是白色,說明應該多流出一次,所以a = wi,j / 2,b = (wi,j + 1) / 2
反之,同理可得a = (wi,j + 1) / 2,b = wi,j / 2
上述除法全部是取下整
構建超級源s,超級匯t
如果某點在原圖是黑色,連s到yi,j容量為1的邊,代表這個黑棋子從這個點出發
如果某點在新圖是黑色,連yi,j到t容量為1的邊,代表必須有乙個黑棋子在這裡停止
最後,根據八連通把x,z之間的邊建完,跑個最小費用最大流就行了
#include#include#include#include#includeusing namespace std;
const int maxn = 1222;
const int maxm = 4e5 + 40;
const int inf = 1e9 + 233;
const int dx[8] = ;
const int dy[8] = ;
struct e
e(int to,int cap,int flow,int cost):
to(to),cap(cap),flow(flow),cost(cost){}
}edgs[maxm];
int n,m,s,t,tot,t1,t2,cnt,num[22][22],a[22][22],b[22][22],cost[maxn],flow[maxn],from[maxn];
char ch[22],s[22][22],t[22][22];
bool vis[maxn];
vector v[maxn];
queue q;
void add(int x,int y,int cap,int cost)
bool spfa()
}return cost[t] != inf;}
int main()
for (int i = 1; i <= n; i++)
if (t1 != t2)
for (int i = 1; i <= n; i++)}}
int maxflow,cost; maxflow = cost = 0;
while (spfa())
}cout << (maxflow == t1 ? cost : -1) << endl;
return 0;
}
BZOJ 2668 cqoi2012 交換棋子
time limit 3 sec memory limit 128 mb submit 1112 solved 409 submit status discuss 有乙個n行m列的黑白棋盤,你每次可以交換兩個相鄰格仔 相鄰是指有公共邊或公共頂點 中的棋子,最終達到目標狀態。要求第i行第j列的格仔只能...
BZOJ2668 cqoi2012 交換棋子
題解 可以戳這裡 其實自己yy一下就知道這樣建圖的正確性了。感覺太神奇,居然還能拆成3個點 orzzzzzzzzzzzzzzzzzzzzzzzzz 跪跪跪跪跪跪跪跪 1 include2 3 include4 5 include6 7 include8 9 include10 11 include1...
bzoj2668 cqoi2012 交換棋子
description 有乙個 n 行 m 列的黑白棋盤,你每次可以交換兩個相鄰格仔 相鄰是指有公共邊或公共頂點 中的棋子,最終達到目標狀態。要求第 i 行第 j 列的格仔只能參與 m 次交換。input 第一行包含兩個整數 n,m 1 le n,m le 20 以下 n 行為初始狀態,每行為乙個包...