【codevs 1902】方格取数3(最小割)
生活随笔
收集整理的這篇文章主要介紹了
【codevs 1902】方格取数3(最小割)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1907 方格取數(shù) 3
時間限制: 2 s ??空間限制: 256000 KB ???題目等級 : 大師 Master
題目描述?Description
? 在一個有m*n 個方格的棋盤中,每個方格中有一個正整數(shù)。現(xiàn)要從方格中取數(shù),使任意2 個數(shù)所在方格沒有公共邊,且取出的數(shù)的總和最大。試設計一個滿足要求的取數(shù)算法。
????編程任務:對于給定的方格棋盤,按照取數(shù)要求編程找出總和最大的數(shù)。
輸入描述?Input Description
???第1 行有2 個正整數(shù)m和n,分別表示棋盤的行數(shù)和列數(shù)。接下來的m行,每行有n個正整數(shù),表示棋盤方格中的數(shù)。
輸出描述?Output Description
??將取數(shù)的最大總和輸出
樣例輸入?Sample Input
? ?3 3
? ?1?2 3
? ?3 2 3
? ?2 3 1
樣例輸出?Sample Output
??11
數(shù)據(jù)范圍及提示?Data Size & Hint
? 在一個有m*n 個方格的棋盤中,每個方格中有一個正整數(shù)。現(xiàn)要從方格中取數(shù),使任意2 個數(shù)所在方格沒有公共邊,且取出的數(shù)的總和最大。試設計一個滿足要求的取數(shù)算法。
????編程任務:對于給定的方格棋盤,按照取數(shù)要求編程找出總和最大的數(shù)。
輸入描述?Input Description
???第1 行有2 個正整數(shù)m和n,分別表示棋盤的行數(shù)和列數(shù)。接下來的m行,每行有n個正整數(shù),表示棋盤方格中的數(shù)。
輸出描述?Output Description
??將取數(shù)的最大總和輸出
樣例輸入?Sample Input
? ?3 3
? ?1?2 3
? ?3 2 3
? ?2 3 1
樣例輸出?Sample Output
??11
數(shù)據(jù)范圍及提示?Data Size & Hint
??n,m<=30
【題解】【網(wǎng)絡流最小割】
【黑白染色,將相鄰兩個格染上不同的顏色,將源點與白點連邊,黑點與匯點連邊,流量為當前格中的值。再將相鄰的點連邊,流量為極大值。然后跑最小割(注:最小割=最大流),故直接跑最大流,最后用所有數(shù)的和減去最大流】?
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> #define lng 10000000 using namespace std; int a[10010],next[10010],p[10010],remain[10010],tot; int dis[10010],cur[10010]; int n,m,ans,sum,n1,cnt,as;inline void add(int x,int y,int z) {tot++; a[tot]=y; next[tot]=p[x]; p[x]=tot; remain[tot]=z;tot++; a[tot]=x; next[tot]=p[y]; p[y]=tot; remain[tot]=0;return; }inline bool bfs() {memset(dis,-1,sizeof(dis));queue<int>que;for (int i=0;i<=n1;++i)cur[i]=p[i];que.push(0); dis[0]=0;while (!que.empty()){int u,v;u=que.front(); que.pop();v=p[u];while (v!=-1) {if (remain[v]&&dis[a[v]]<0){dis[a[v]]=dis[u]+1;que.push(a[v]);}v=next[v];}}if (dis[n1]<0) return false;else return true; } inline int dfs(int now,int flow) {if (now==n1||!flow) return flow;int u=cur[now],s;while (u!=-1){cur[now]=u;if (dis[a[u]]>0&&dis[a[u]]==dis[now]+1&&(s=dfs(a[u],min(flow,remain[u])))){remain[u]-=s; remain[u^1]+=s;return s;}u=next[u];}return 0; } int main() {int i,j;memset(p,-1,sizeof(p));memset(next,-1,sizeof(next));scanf("%d%d",&n,&m);n1=n*m+1;as=ans=sum=cnt=0; tot=-1;for (i=1;i<=n;++i)for (j=1;j<=m;++j){int x;cnt++;scanf("%d",&x);ans+=x;if (i%2==j%2){add(0,cnt,x);if (i==1) add(cnt,cnt+m,lng);if (i==n) add(cnt,cnt-m,lng);if (i>1&&i<n) {add(cnt,cnt+m,lng); add(cnt,cnt-m,lng);}if (j==1) add(cnt,cnt+1,lng);if (j==m) add(cnt,cnt-1,lng);if (j>1&&j<m) {add(cnt,cnt+1,lng); add(cnt,cnt-1,lng);}}else add(cnt,n1,x); }while (bfs())while (as=dfs(0,0x7fffffff))sum+=as;ans-=sum;printf("%d\n",ans);return 0; }
總結
以上是生活随笔為你收集整理的【codevs 1902】方格取数3(最小割)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新疆计算机系一级教程,新疆计算机一级
- 下一篇: 远程预付费管理系统在淮安茂业时代广场 项