日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[codevs 1907] 方格取数3

發布時間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [codevs 1907] 方格取数3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[codevs 1907] 方格取數3


題解:

二分圖染色、最大點權獨立集。
因為要用到最大獨立集的一些思路,故先寫了一篇最大獨立集的題解:http://blog.csdn.net/qq_21110267/article/details/43371311
最大點權獨立集可以類比到最大獨立集,同樣求解它的對稱問題——最小點權覆蓋問題(思路見上),點權和-最小點權覆蓋=最大點權獨立集。
那么怎么求最小點權覆蓋呢? 想一想最小割模型,割的性質是不存在一條s-t的路徑,我們已經建立了二分圖模型,假設u是左側的結點,v是右側的結點,那么s-u、u-v、v-t必定有一條在最小割中,如果人為的令u-v不在最小割中(設邊權為INF),那么就簡化為了s-u、v-t至少一條邊在最小割中,正符合了最小點權覆蓋中相鄰點(u、v)至少一個點被選中,我們把s-u的容量設為點u的權值,v-t的容量設為點t的權值,這樣s-u在最小割中就對應著u被選中,而v-t在最小割中就對應著v被選中,這樣就把最小點權覆蓋問題轉化為了最大流問題。

代碼:

總時間耗費: 3ms?
總內存耗費: 492B

#include<cstdio> #include<iostream> #include<vector> #include<queue> #include<algorithm> using namespace std;const int maxn = 1000 + 10; const int INF = 1000000007;struct Edge {int from, to, cap, flow; };vector<Edge> edges; vector<int> G[maxn]; int val[maxn][maxn];void AddEdge(int from, int to, int cap) {edges.push_back((Edge){from, to, cap, 0});edges.push_back((Edge){to, from, 0, 0});int sz = edges.size();G[from].push_back(sz-2);G[to].push_back(sz-1); }int m, n, s, t; int d[maxn], p[maxn], cur[maxn], num[maxn];bool vis[maxn]; bool BFS() {memset(vis, 0, sizeof(vis));queue<int> Q;Q.push(s);d[s] = 0;vis[s] = 1;while(!Q.empty()) {int x = Q.front(); Q.pop();for(int i = 0; i < G[x].size(); i++) {Edge& e = edges[G[x][i]];if(!vis[e.to] && e.cap > e.flow) {vis[e.to] = true;d[e.to] = d[x] + 1;Q.push(e.to);}}}return vis[t]; }int DFS(int u, int a) {if(u == t || a == 0) return a;int flow = 0, f;for(int &i = cur[u]; i < G[u].size(); i++) {Edge& e = edges[G[u][i]];if(d[u] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) {e.flow += f;edges[G[u][i]^1].flow -= f;flow += f;a -= f;if(a == 0) break;}}return flow; }int Maxflow() {int flow = 0;while(BFS()) {memset(cur, 0, sizeof(cur));flow += DFS(s, INF);}return flow; }int main() {cin >> m >> n;s = 0; t = m * n + 1;int tot = 0;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++) {cin >> val[i][j];tot += val[i][j];}for(int i = 0; i < m; i++)for(int j = 0; j < n; j++) {int u = i*n + j + 1;if((i+j)&1) {if(i > 0) AddEdge(u, u-n, INF);if(j > 0) AddEdge(u, u-1, INF);if(i < m-1) AddEdge(u, u+n, INF);if(j < n-1) AddEdge(u, u+1, INF);AddEdge(s, u, val[i][j]); } else {AddEdge(u, t, val[i][j]);}}int ans = Maxflow();cout << tot - ans << endl;return 0; }

總結

以上是生活随笔為你收集整理的[codevs 1907] 方格取数3的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。