在乙個有 m*n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數。
第 1 行有 2 個正整數 m 和 n,分別表示棋盤的行數和列數。接下來的 m 行,每行有 n 個正整數,表示棋盤方格中的數。
程式執行結束時,將取數的最大總和輸出
考慮網路流。
把每個可以同時選的兩個點建邊,最後要使流量最大 可是n
<=
100 n
<=
100,邊的數量就會**
不如換種方式考慮。
假設先把全部的選上,然後把不滿足的刪掉,要使刪掉的數量盡可能小。
這樣就有了一種最小割的感覺。
將所有點按照所在行和列之和的奇偶性分成兩部分(因為與乙個點相鄰的點奇偶性不同,就形成了一張二分圖)
建圖:
1. 將s與每個奇點相連,權值為這個點的價值(意思是將這個點刪除要花費w的代價)
2. 同理將每個偶點與t相連,權值為這個點的價值
3. 從每個奇點向相鄰的每個偶點連一條權值為inf的邊,說明這兩個點必然至少有乙個會被刪掉。
然後跑一邊最小割。
因為最小割求的是要使刪的數目最小,所以答案是總和-最小割。
洛谷上可以測
#include
#include
#include
#include
using
namespace
std;
#define maxn 1000010
const
int inf=1e9+7;
inline
int read()
while(ch>='0'&&ch<='9')
return ret*ff;
}int n,m,s,t;
struct edgee[maxn];
int ecnt=1;
int head[maxn],dis[maxn];
void addedge(int u,int v,int w)
void addedge(int u,int v,int w)
int dfs(int x,int nar)
if(!used) dis[x]=-1;
return used;
}bool bfs()
}return dis[t]!=inf;
}int dinic()
return ans;
}int main()
else addedge(p,t,c);}}
printf("%d\n",sum-dinic());
return
0;}
網路流24題 09 方格取數問題
問題描述 在乙個有m n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任 意2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。程式設計任務 對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數。資料輸入 由檔案grid.in提供輸入資料。檔案第1 ...
網路流24題 13 方格取數問題
這道題與上一道騎士共存問題非常的類似,首先也是黑白染色得到一張二分圖,s向黑連邊,白向t連邊,流量均為點權,然後黑點與會起衝突的白點連邊,那麼如果有一條從s 黑 白 t的路徑,證明有衝突,我們以割掉這條邊 黑點與s的連邊,白點與t連邊 表示拿走這個點,希望剩下的權值最大,所以模型轉換為最小割。求個最...
24題 方格取數問題 網路流
在乙個有 n m n times m n m 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。這道題明顯是乙個二分圖。我們可以把每個點染色,將i j i ji j為偶數的點連向t tt,否則連向s ss。那麼對於每乙個連s ss的白...