[BZOJ2127]happiness

來源:互聯網
上載者:User

標籤:.com   左右   mes   turn   容量   getchar   直接   資料規模   畢業   

題面戳我

Description

高一一班的座位表是個n*m的矩陣,經過一個學期的相處,每個同學和前後左右相鄰的同學互相成為了好朋友。這學期要分文理科了,每個同學對於選擇文科與理科有著自己的喜悅值,而一對好朋友如果能同時選文科或者理科,那麼他們又將收穫一些喜悅值。作為電腦競賽教練的scp大老闆,想知道如何分配可以使得全班的喜悅值總和最大。

Input

第一行兩個正整數n,m。
接下來是六個矩陣第一個矩陣為n行m列
此矩陣的第i行第j列的數字表示座位在第i行第j列的同學選擇文科獲得的喜悅值。
第二個矩陣為n行m列
此矩陣的第i行第j列的數字表示座位在第i行第j列的同學選擇理科獲得的喜悅值。
第三個矩陣為n-1行m列
此矩陣的第i行第j列的數字表示座位在第i行第j列的同學與第i+1行第j列的同學同時選擇文科獲得的額外喜悅值。
第四個矩陣為n-1行m列
此矩陣的第i行第j列的數字表示座位在第i行第j列的同學與第i+1行第j列的同學同時選擇理科獲得的額外喜悅值。
第五個矩陣為n行m-1列
此矩陣的第i行第j列的數字表示座位在第i行第j列的同學與第i行第j+1列的同學同時選擇文科獲得的額外喜悅值。
第六個矩陣為n行m-1列
此矩陣的第i行第j列的數字表示座位在第i行第j列的同學與第i行第j+1列的同學同時選擇理科獲得的額外喜悅值。

Output

輸出一個整數,表示喜悅值總和的最大值

Sample Input

1 2
1 1
100 110
1
1000

Sample Output

1210

【範例說明】

兩人都選理,則獲得100+110+1000的喜悅值。

【資料規模】

對於100%的資料,n,m<=100 所有喜悅值均為小於等於5000的非負整數

sol

首先把最大受益轉化成最小損失從而建立最小割模型。把每個矩陣中的每個數字都先加起來,然後用最小割求解最小損失。
下文中,我們用二元組\((p,q)\)來表示網路中從\(p\)連到\(q\)的邊的容量。
我們把選文科的劃在\(S\)這一邊,把選理科的劃在\(T\)這一邊。那麼這樣對一個單點\(x\)的處理就很簡單:直接令\((S,x)=\)選文科的收益,\((x,T)=\)選理科的收益即可。
但是兩人同時選文或選理的收益(或者說損失)要怎麼計算呢?
我們考慮兩個人\(x\),\(y\),他們倆一起選文的收益是\(u\),一起選理的收益是\(v\)。我們對於可能出現的\(2^2=4\)種情況分別討論。
1、\(x\),\(y\)都選文。此時被割掉的邊是\((x,T)\)和\((y,T)\),總損失應為\(v\);
2、\(x\),\(y\)都選理。此時被割掉的邊是\((S,x)\)和\((S,y)\),總損失應為\(u\);
3、\(x\)選文\(y\)選理。此時被割掉的邊是\((x,T)\)、\((S,y)\)和\((x,y)\),總損失應為\(u+v\);
4、\(x\)選理\(y\)選文。此時被割掉的邊是\((S,x)\)、\((y,T)\)和\((y,x)\),總損失應為\(u+v\)。
由上我們可以得到一個方程組:

\((x,T)+(y,T)=v\)
\((S,x)+(S,y)=u\)
\((x,T)+(S,y)+(x,y)=u+v\)
\((S,x)+(y,T)+(y,x)=u+v\)

(我太菜了實在是寫不出部落格園markdown的方程組。。。只能寫公式形式了)
只要是初中數學畢業了的就知道這個方程肯定解不出來(不定方程),但是考慮到這個東西並不會對其他產生影響,所以我們可以任意帶一組可行解進去。
令:

$(x,T) = v / 2 $
$(y,T) = v / 2 $
$(S,x) = u / 2 $
$(S,y) = u / 2 $
$(x,y) = (u + v) / 2 $
$(y,x) = (u + v) / 2 $

按照以上建圖方式即可。
由於除以二了以後可能會產生浮點數問題,所以考慮把所有邊擴大兩倍,保證所有容量是正整數。

code
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int inf = 1e9;const int N = 110;struct edge{int to,next,w;}a[N*N<<3];int n,m,P[N][N],tot,v[6][N][N],S,T,head[N*N],cnt=1,dep[N*N],cur[N*N],sum;queue<int>Q;int gi(){    int x=0,w=1;char ch=getchar();    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();    if (ch=='-') w=0,ch=getchar();    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();    return w?x:-x;}void link(int u,int v,int w,bool b){    a[++cnt]=(edge){v,head[u],w};    head[u]=cnt;    a[++cnt]=(edge){u,head[v],b?w:0};    head[v]=cnt;}bool bfs(){    memset(dep,0,sizeof(dep));    dep[S]=1;Q.push(S);    while (!Q.empty())    {        int u=Q.front();Q.pop();        for (int e=head[u];e;e=a[e].next)            if (a[e].w&&!dep[a[e].to])                dep[a[e].to]=dep[u]+1,Q.push(a[e].to);    }    return dep[T];}int dfs(int u,int flow){    if (u==T)        return flow;    for (int &e=cur[u];e;e=a[e].next)        if (a[e].w&&dep[a[e].to]==dep[u]+1)        {            int temp=dfs(a[e].to,min(a[e].w,flow));            if (temp) {a[e].w-=temp;a[e^1].w+=temp;return temp;}        }    return 0;}int Dinic(){    int res=0;    while (bfs())    {        for (int i=T;i;i--) cur[i]=head[i];        while (int temp=dfs(S,inf)) res+=temp;    }    return res;}int main(){    n=gi();m=gi();S=n*m+1;T=n*m+2;    for (int i=1;i<=n;i++)        for (int j=1;j<=m;j++)            P[i][j]=++tot;    for (int k=0;k<6;k++)    {        int x=n,y=m;        if (k==2||k==3) x--;        if (k==4||k==5) y--;        for (int i=1;i<=x;i++)            for (int j=1;j<=y;j++)                v[k][i][j]=gi(),sum+=v[k][i][j];    }    for (int i=1;i<=n;i++)        for (int j=1;j<=m;j++)        {            link(S,P[i][j],(v[0][i][j]<<1)+v[2][i][j]+v[2][i-1][j]+v[4][i][j]+v[4][i][j-1],0);            link(P[i][j],T,(v[1][i][j]<<1)+v[3][i][j]+v[3][i-1][j]+v[5][i][j]+v[5][i][j-1],0);            if (i<n)                link(P[i][j],P[i+1][j],v[2][i][j]+v[3][i][j],1);            if (j<m)                link(P[i][j],P[i][j+1],v[4][i][j]+v[5][i][j],1);        }    printf("%d\n",sum-(Dinic()>>1));    return 0;}

[BZOJ2127]happiness

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.