bzoj 2127 happiness【網路流dinic】

來源:互聯網
上載者:User

標籤:body   cout   ios   png   using   turn   串連   方法   iostream   

參考:https://www.cnblogs.com/chenyushuo/p/5144957.html 不得不說這個建圖方法真是非常妙啊
假設S點選理,T點選文,a[i][j]為(i,j)選文收益,b[i][j]為(i,j)選理收益,c[i][j]為同時選文收益,d[i][j]為同時選文收益。
那麼對於每個點x=(i+1)*m+j,我們串連
\[ c[s,x]=b[i][j] \]
\[ c[x,t]=a[i][j] \]
對於有利益相關的x,y兩點,串連
\[ c[s,x]=d[i][j]/2 \]
\[ c[s,y]=d[i][j]/2 \]
\[ c[x,t]=c[i][j]/2 \]
\[c[y,t]=c[i][j]/2 \]
\[ c[x,y]=c[i][j]/2+d[i][j]/2 \]
\[ c[y,x]=c[i][j]/2+d[i][j]/2 \]
建完的圖:

然後考慮最小割,下面枚舉幾種情況:
都選文,即割掉了x選理,y選理和(x,y)都選理:

都選理,即割掉了x選文,y選文和(x,y)都選文:

x選文y選理,即割掉了x選理,y選文,(x,y)都選理/+(x,y)都選理/2+(x,y)都選文/2+(x,y)都選文/2,即,割掉x選理,y選文,(x,y)都選理,(x,y)都選文:

y選文x選理,即割掉了x選文,y選理,(x,y)都選理/+(x,y)都選理/2+(x,y)都選文/2+(x,y)都選文/2,即,割掉x選文,y選理,(x,y)都選理,(x,y)都選文:

對於除以2的操作,為避免下取整的誤差,我們選擇把所有流量都*2,最後再/2。
$ ans=sum(全部收益)- 最小割 $
p.s.用鄰接表建圖的時候先把每個點選單科的邊連上,再練同時選的收益,否則會重

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int N=105,E=1000005,inf=1e9,P=500005;int n,m,a[N][N],b[N][N],c[N][N],d[N][N],s,t,sum,cnt=1,h[P],le[N*N];struct qwe{    int ne,to,va;}e[E];int read(){    int r=0;    char p=getchar();    while(p<‘0‘||p>‘9‘)        p=getchar();    while(p>=‘0‘&&p<=‘9‘)    {        r=r*10+p-48;        p=getchar();    }    return r;}void add(int u,int v,int w){    cnt++;    e[cnt].ne=h[u];    e[cnt].to=v;    e[cnt].va=w;    h[u]=cnt;}bool bfs(){    queue<int>q;    memset(le,0,sizeof(le));    le[s]=1;    q.push(s);    while(!q.empty())    {        int u=q.front();//cout<<u<<"AAAAAAAAAAAA"<<endl;        q.pop();        for(int i=h[u];i;i=e[i].ne)            if(e[i].va&&!le[e[i].to])            {                le[e[i].to]=le[u]+1;                q.push(e[i].to);            }    }    // for(int i=0;i<=5;i++)        // cout<<le[i]<<" ";    return le[t]; }int dfs(int u,int f){//cout<<u<<" "<<f<<endl;    if(u==t)    {        //cout<<"!!";        return f;    }    int used=0;    for(int i=h[u];i;i=e[i].ne)    {        //cout<<u<<" "<<e[i].to<<"   "<<e[i].va<<endl;;        if(e[i].va>0&&le[e[i].to]==le[u]+1)        {//cout<<"OK"<<endl;            int w=dfs(e[i].to,min(f-used,e[i].va));            e[i].va-=w;            e[i^1].va+=w;            used+=w;            if(used==f)                return f;        }    }    if(!used)        le[u]=-1;    return used;}int dinic(){    int ans=0;    while(bfs())        ans+=dfs(s,inf);//,cout<<ans<<endl;    return ans;}int main(){    n=read(),m=read();    s=0,t=n*m+1;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            a[i][j]=read(),sum+=a[i][j];    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            b[i][j]=read(),sum+=b[i][j];    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        {            int x=(i-1)*m+j;            add(s,x,b[i][j]<<1);            add(x,s,0);            add(x,t,a[i][j]<<1);            add(t,x,0);        }    for(int i=1;i<n;i++)        for(int j=1;j<=m;j++)            c[i][j]=read(),sum+=c[i][j];    for(int i=1;i<n;i++)        for(int j=1;j<=m;j++)            d[i][j]=read(),sum+=d[i][j];    for(int i=1;i<n;i++)        for(int j=1;j<=m;j++)        {            int x=(i-1)*m+j,y=i*m+j;            add(s,x,d[i][j]);            add(x,s,0);            add(s,y,d[i][j]);            add(y,s,0);            add(x,y,c[i][j]+d[i][j]);            add(y,x,c[i][j]+d[i][j]);            add(x,t,c[i][j]);            add(t,x,0);            add(y,t,c[i][j]);            add(t,y,0);        }    for(int i=1;i<=n;i++)        for(int j=1;j<m;j++)            c[i][j]=read(),sum+=c[i][j];    for(int i=1;i<=n;i++)        for(int j=1;j<m;j++)            d[i][j]=read(),sum+=d[i][j];    for(int i=1;i<=n;i++)        for(int j=1;j<m;j++)        {            int x=(i-1)*m+j,y=(i-1)*m+j+1;            add(s,x,d[i][j]);            add(x,s,0);            add(s,y,d[i][j]);            add(y,s,0);            add(x,y,c[i][j]+d[i][j]);            add(y,x,c[i][j]+d[i][j]);            add(x,t,c[i][j]);            add(t,x,0);            add(y,t,c[i][j]);            add(t,y,0);        }    printf("%d\n",sum-(dinic()>>1));    return 0;}

bzoj 2127 happiness【網路流dinic】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.