P3159 CQOI2012 交換棋子

2022-05-08 02:24:09 字數 1906 閱讀 3083

有乙個n行m列的黑白棋盤,你每次可以交換兩個相鄰格仔(相鄰是指有公共邊或公共頂點)中的棋子,最終達到目標狀態。要求第i行第j列的格仔只能參與mi,j次交換。

第一行包含兩個整數n,m(1<=n, m<=20)。以下n行為初始狀態,每行為乙個包含m個字元的01串,其中0表示黑色棋子,1表示白色棋子。以下n行為目標狀態,格式同初始狀態。以下n行每行為乙個包含m個0~9數字的字串,表示每個格仔參與交換的次數上限。

輸出僅一行,為最小交換總次數。如果無解,輸出-1。

輸入 #1複製

3 3

110000

001000

110100

222222

222

輸出 #1複製

4
對於棋盤的初始狀態和最終狀態可以看做二分圖的兩組點,而棋子的上下左右移動可以視作邊的。交換黑白點可以視作講黑子進行移動,每次費用為1,因此我們可以進行建圖,但這題十分的特殊,因為它限制了每個格仔的交換次數,並且用平常的拆點,我們無法表示它是否停留在改點,因此我們將1個點拆為3個點。分別為(left,now,right),每個點從left進入,停留在now上,從right出去。但對於兩條邊,它所限制的交換次數該如何劃分又是乙個問題。我們不妨把它視作黑點移動經過的次數。

設limt表示限制數。

對於初始和結果相同的點,邊的為(l,now,limt/2,1),(now,r,limt/2,1)。

對於初始為黑,結果為白的情況邊為(l,now,limt/2,1),(now,r,(limt+1)/2,1)。

對於初始為白,結果為黑的情況則與之相反。

原理:如果開始為黑,結果為白,則黑點一定要移動出去,則若limt為奇數時,多餘的1應該加入出邊。若為偶數,則加1不會對其有影響。另一種情況與之相反。

最後將源點和匯點連入圖中,跑最大流最小費用即可。

#include#define n 10700

#define m 107000

#define inf 1<<29

#define cnt (n*m*3)

#define left(i,j) ((i-1)*m+j)

#define now(i,j) (((i-1)*m+j)+n*m)

#define right(i,j) (((i-1)*m+j)+(n*m<<1))

using

namespace

std;

struct

nodee[m*2

];int tot=1,head[n],maxflow=0,ans=0

;int

n,m,s,t;

void add(int x,int y,int z,int

p)int

incf[n],v[n],pre[n],d[n];

bool

spfa()}}

if(d[t]==0x3f3f3f3f) return

false;//

0xcfcfcfcf

return

true;}

void

update()

maxflow+=incf[t];

ans+=d[t]*incf[t];

}int

x1[n][n],x2[n][n],z[n][n];

int dx[9]=;

int dy[9]=;

intmain()}}

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

if(t1!=t2)

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

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

while

(spfa()) update();

if(maxflow==t1) coutelse cout<<"-1"

}

P3159 CQOI2012 交換棋子

相當神奇的費用流拆點模型 最開始我想到把交換黑色棋子看成乙個流流動的過程,流從乙個節點流向另乙個節點就是交換兩個節點,然後把乙個位置拆成兩個點限制流量,然後就有了這樣的建圖方法 s向所有初始是黑色點的入點連cap 1,cost 0的邊,最後是黑色點的出點向t連一條cap 1,cost 0的邊,然後對...

P3159 CQOI2012 交換棋子 網路流

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

2668 cqoi2012 交換棋子

time limit 3 sec memory limit 128 mb submit 1136 solved 423 submit status discuss 有乙個n行m列的黑白棋盤,你每次可以交換兩個相鄰格仔 相鄰是指有公共邊或公共頂點 中的棋子,最終達到目標狀態。要求第i行第j列的格仔只能...