bzoj2132 圈地計畫(無比強大的最小割)

2022-08-01 17:48:12 字數 1959 閱讀 4481

題目:傳送門

簡要題意:

給出乙個矩陣,一共n*m個點,並給出三個收益矩陣。a矩陣表示這個點建a的可取收益,b矩陣表示這個點建b的可取收益,c矩陣表示如果相鄰(有且僅有一條公共邊)的點和自己所建的建築不一樣,則可獲得c[i][j]的收益,如果相鄰的有k個點和自己不一樣,則收益為k*c[i][j]。求最大收益。

題解:日常一模最小割%%%orz

本蒟蒻其實也看出是最小割什麼的,但是怎麼割啊。。。

可能有人會和我有一樣的疑惑:

按照正常的割法建圖:st到x連a收益,x到ed連b收益,兩兩之間再連c收益

連完之後就蒙b了...割出來的是什麼鬼???

這時我們會發現,這樣子連的話負權邊根本沒有體現啊???

%題解啊啊啊:

正解其實是需要進行黑白染色的(原因後面講)

染完色之後:st到黑點連a收益,黑點到ed連b收益;白點反之,然後相鄰的不同顏色的格仔相互連邊(其實就是每個點還要連出去上下左右的點,因為染色了啊)

這樣之後用sum-最小割就ok。

那染色是什麼鬼:

正確答案並不一定是相鄰的點顏色都不一樣,那麼染色的目的就不是保證收益最大。

但是染完色之後再跑最小割我們可以發現:

如果某相鄰兩點異色的收益不如同色的收益,那麼這條路徑上關於相鄰異色的收益肯定會被割掉

如果異色收益更優,那割掉的肯定是乙個a收益加乙個b收益

那麼肯定是要最小割啊~

**:

1 #include2 #include3 #include4 #include5 #include6

#define qread(x) x=read()

7using

namespace

std;

8 inline int

read()912

while(ch>='

0' && ch<='9')

13return f*x;14}

15struct

node

16a[1110000];int len,last[110000

];19

intn,m,st,ed,head,tail;

20void ins(int x,int y,int

c)21

34int list[11000],h[110000

];35

bool

bt_h()

3650

}51 head++;52}

53if(h[ed]>0)return

true;54

return

false;55

}56int find_flow(int x,int

flow)

5768}69

if(s==0)h[x]=0;70

return

s;71}72

int a[110][110],b[110][110],c[110][110

];73

int f[110][110];//

黑白染色 1為黑 2為白

74int d[110][110

];75

intmain()

7693

int sum=0;94

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

95for(int j=1;j<=m;j++)

96103

else

104108

}109

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

110for(int j=1;j<=m;j++)

111117

int ans=0

;118

while(bt_h())ans+=find_flow(st,999999999

);119 printf("

%d\n

",sum-ans);

120return0;

121 }

bzoj2132 圈地計畫

有個n m的矩形,每個區域可以建造商業區或工業區,分別獲得ai,j和bi,j的收益。乙個格仔如果有與其相鄰的k個格仔與其型別不同,則可以帶來ci,j的收益。求最大收益 我們可知,i,j和k,l兩個格仔型別不同就會帶來ci,j ck,l的收益。這是經典的二元關係,是網路流問題。x選商業 x選工業 y選...

bzoj 2132 圈地計畫

time limit 2 sec memory limit 256 mb submit 918 solved 417 submit status discuss 最近房地產商gdoi group of dumbbells or idiots 從noi nuts old idiots 手中得到了一塊開...

BZOJ2132 圈地計畫

bzoj2132 圈地計畫 最近房地產商gdoi group of dumbbells or idiots 從noi nuts old idiots 手中得到了一塊開發土地。據了解,這塊土地是一塊矩形的區域,可以縱橫劃分為n m塊小區域。gdoi要求將這些區域分為商業區和工業區來開發。根據不同的地形...