codevs 1907 方格取數 3

2022-05-21 13:03:12 字數 1679 閱讀 7817

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

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

對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數,將取數的最大總和輸出。

3 31 2 3

3 2 3

2 3 1 

n,m<=30

嗯......這道題大概算是自己想出來的第一道網路流的題吧?

雖然想了很久,wa了很多發,但終於a掉了......

網路流的題真是難想(但這一題還是比較簡單的),如果不是我已經知道這道題要用網路流做,還不知道要想到什麼時候去了......

好了,不扯多了,進正題:

首先,我們發現直接建模的話非常不好搞,體重的條件不好表示......

於是,我們就想,是否可以把我們選完數之後剩下的數給表示出來呢?我們發現這個不難做到。只需將棋盤黑白二染色,把黑點、白點各看成一塊,相鄰的格仔間有邊相連,不難發現將黑白兩塊分開的割的方案就是不選的點的合法方案(腦補一下應該可以搞出來)。所以最小割即是合法方案中選出的點和最大的方案。於是我們可以從源點向所有黑(白)點連一條容量為這個格仔裡的數的邊,從黑(白)點向相鄰的點連一條容量為inf的邊,再從白(黑)點向匯點連一條容量為當前格仔裡的數的邊,跑一邊最大流即可得出不選的點的最小和,用所有數字之和減去它就是答案。

update:其實這就是最大獨立集等於總點數減去最大匹配數

下面貼**:

1 #include2 #include3 #include4 #include5 #include6

#define maxm 100010

7#define inf (1<<25)

8#define r(j) (j^1)910

using

namespace

std;

11 typedef long

long

llg;

1213

int head[101*101],next[maxm],to[maxm],c[maxm],tt=1;14

int a[101][101],zx[4]=,zy[4]=;

15int

d[maxm],l,r,dep[maxm],ans,tut,s,t,n,m;

1617

intgetint()

2526

void link(int x,int y,int

z)31

32bool

bfs()42}

43return dep[t]>0;44

}4546int dfs(int u,int

low)

55return

res;56}

5758

intmain()76}

77}78else

link(now,t,a[i][j]);

79 tut+=a[i][j];80}

81while

(bfs())

82while(int tot=dfs(s,inf)) ans+=tot;

83 printf("

%d\n

",tut-ans);

84return0;

85 }

codevs 1907 方格取數3

這個系列終於做完了。又是一道網路流 因為不能取相鄰的點,很容易發現需要二分圖 一半的點連源,另一半連匯,流量為map i,j 相鄰的點連起來,流量為inf 答案就是總和減最大流 最大流。看這篇吧 include include include include define inf 0x3f3f3f3...

Codevs 1907 方格取數 3 最小割

傳送門 1907 方格取數 3 思路 直接求取哪些不好求,但是我們可以求要捨棄哪些,將所有格仔分成兩部分,使得每一部分中都沒有相鄰的格仔,然後一部分連線源點,另一部分連線匯點,權值為格仔中的數字,兩部分中原本相鄰的格仔之間連邊,權值為inf,這樣圖中任意乙個割即為可以捨棄的一種組合,最小割就是所有可...

1907 方格取數 3

時間限制 2 s 空間限制 256000 kb 題目等級 大師 master 題解檢視執行結果 問題描述 在乙個有m n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任 意2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。程式設計任務 對於給定的方格棋...