P2774 方格取數問題

2022-03-04 03:52:05 字數 1716 閱讀 9225

none!

在乙個有 m*n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數。

輸入格式:

第 1 行有 2 個正整數 m 和 n,分別表示棋盤的行數和列數。接下來的 m 行,每行有 n 個正整數,表示棋盤方格中的數。

輸出格式:

程式執行結束時,將取數的最大總和輸出

輸入樣例#1:

3 3

1 2 3

3 2 3

2 3 1

輸出樣例#1:

11

m,n<=100

solution:

網路流套路題。

乙個點若選,會使得其四方向鄰格不能被選,若以座標和的奇偶性為基準,則圖會被分為兩部分,不難發現同一部分的點是不會互相影響的,這恰好是二分圖的形式。

我們從$s$向所有奇數點連點值大小的邊,從偶數點向$t$連點值大小的邊,然後從奇數點向受影響的偶數點連inf的邊。由於要求的是點值和最大的情況,先要使選的情況合法(即使$s,t$不聯通),且不選的點值和最小,那麼這不就是最小割嘛!所以只要用點值和-最小割就是答案了。(好套路的黑白點啊)

**:

/*

code by 520 -- 8.25

*/#include

#define il inline

#define ll long long

#define re register

#define for(i,a,b) for(re int (i)=(a);(i)<=(b);(i)++)

#define bor(i,a,b) for(re int (i)=(b);(i)>=(a);(i)--)

#define debug printf("%d %s\n",__line__,__function__)

using

namespace

std;

const

int n=100005,inf=233333333,dx[4]=,dy[4]=;

int n,m,s,t,dis[n],to[n],net[n],w[n],h[n],cnt=1

;int mp[105][105

],ans;

il int id(int x,int y)

il void add(int u,int v,int

c)queue

q;il bool

bfs()

return dis[t]!=-1;}

int dfs(int u,int

op) }

if(!flow) dis[u]=-1

;

return

flow;

}il

void

init()

for(i,

1,n) for(j,1

,m)

if((i+j)&1

) }

while(bfs()) ans-=dfs(s,inf);

cout

<}int

main()

P2774 方格取數問題

題目描述 在乙個有 m n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數。輸入格式 第 1 行有 2 個正整數 m 和 n,分別表示棋盤的行...

P2774 方格取數問題

對棋盤黑白染色,源點向黑點連邊,匯點向白點連邊,權值均為這個點的權值。然後所有的黑點向白點連一條 inf 的邊。這樣求出的最小割一定會割掉與源點和匯點相連的邊,割掉這條邊相當於不選這個點。所以最後答案就是所有點的權值 最小割。include include include include defin...

P2774 方格取數問題

傳送門 考慮一開始把所有點都選了,再放棄一些點使得選擇合法 考慮求出最小的放棄掉的價值 看到棋盤先黑白染色冷靜一下 從 s 向所有黑點連一條流量為點權的邊,如果滿流表示我放棄這個點的價值 從所有白點向所有 t 連邊,如果滿流說明我放棄這個點的價值 從所有黑點 x 向它四個方向的四個白點 a,b,c,...