其他分享
首页 > 其他分享> > [六省联考2017]寿司餐厅(网络流+最大权闭合子图)

[六省联考2017]寿司餐厅(网络流+最大权闭合子图)

作者:互联网

这是一道比较好的网络流题。

看到这题,除了指数级别的暴力和所有a[i]相同的DP,并没有啥办法,只能有70pts。然后一眼就是网络流,考虑把区间变为点,对于(i,j),如果选了,则必须选(i+1,j)和(i,j-1),流量为inf。然后根据d[i][j]的正负性,正的就由源点连边,反之连向汇点。当且仅当i=j的区间,需要向每一个寿司连边,发现每种寿司选c次,计算c个id和1个m*id2,然后对每一种寿司连m*id2的流量,表示选了这种寿司一定会花这些钱,然后对每个寿司连流量id的边到其种类即可。

#include<bits/stdc++.h>
using namespace std;
const int N=13005;
struct edge{int v,nxt,w;}e[N*10];
int n,m,ecnt=1,S,T,ans,cnt,hd[N],bel[120],d[120][120],id[120][120],lv[N];
void adde(int x,int y,int z)
{
    e[++ecnt]=(edge){y,hd[x],z},hd[x]=ecnt;
    e[++ecnt]=(edge){x,hd[y],0},hd[y]=ecnt;
}
bool bfs()
{
    queue<int>q;q.push(S);
    memset(lv,0,sizeof lv);
    lv[S]=1;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        if(u==T)return 1;
        for(int i=hd[u];i;i=e[i].nxt)
        if(!lv[e[i].v]&&e[i].w)lv[e[i].v]=lv[u]+1,q.push(e[i].v);
    }
    return lv[T];
}
int dfs(int u,int low)
{
    if(u==T||!low)return low;
    int sum=0;
    for(int i=hd[u];i&&low;i=e[i].nxt)
    if(lv[e[i].v]==lv[u]+1&&e[i].w)
    {
        int tmp=dfs(e[i].v,min(low,e[i].w));
        if(tmp>0)e[i].w-=tmp,e[i^1].w+=tmp,sum+=tmp,low-=tmp;
    }
    if(!sum)lv[u]=-1;
    return sum;
}
int main()
{
    scanf("%d%d",&n,&m);
    T=12500;
    for(int i=1;i<=n;i++)scanf("%d",&bel[i]);
    for(int i=1;i<=n;i++)
    for(int j=i;j<=n;j++)
    scanf("%d",&d[i][j]);
    for(int i=1;i<=1000;i++)adde(n+i,T,m*i*i);
    for(int i=1;i<=n;i++)adde(i,n+bel[i],1e9),adde(i,T,bel[i]);
    cnt=n+1000;
    for(int i=1;i<=n;i++)
    for(int j=i;j<=n;j++)
    id[i][j]=++cnt;
    for(int i=1;i<=n;i++)
    {
        adde(id[i][i],i,1e9);
        if(d[i][i]>0)ans+=d[i][i],adde(S,id[i][i],d[i][i]);
        else adde(id[i][i],T,-d[i][i]);
    }
    for(int i=1;i<=n;i++)
    for(int j=i+1;j<=n;j++)
    {
        adde(id[i][j],id[i][j-1],1e9),adde(id[i][j],id[i+1][j],1e9);
        if(d[i][j]>0)ans+=d[i][j],adde(S,id[i][j],d[i][j]);
        else adde(id[i][j],T,-d[i][j]);
    }
    while(bfs())ans-=dfs(S,1e9);
    printf("%d",ans);
}
View Code

 

标签:tmp,六省,int,子图,id,lv,low,联考,hd
来源: https://www.cnblogs.com/hfctf0210/p/11122779.html