洛谷 P3749 [六省联考 2017] 寿司餐厅 分析
最大权闭合子图 的模型
模型:有若干个物品,每种物品有一个价值 $v_i$,选取了物品就意味着获得了价值。
物品之间有限制关系:$x \to y$ 表示若要选择物品 $x$ 则必须选择物品 $y$。目标是最大化价值和。
解法
考虑使用最小割解决此类问题:
将每个物品与源点 $s$ 和汇点 $t$ 相连。若割掉与 $s$ 相连的边表示不选这个物品,割掉与 $t$ 相连的边表示选择这个物品。
对于一个物品的价值 $v$,如果 $v>0$ 则令它与 $s$ 相连的边的权值为 $v$,与 $t$ 相连的边的权值为 $0$,将 $v$ 加入答案。表示不选择这个物品会付出 $v$ 的代价;如果 $v<0$ 则令它与 $s$ 相连的边的权值为 $0$,与 $t$ 相连的边的权值为 $-v$,表示选择这个物品会付出 $-v$ 的代价。
对于 $x \to y$ 的关系,转化为 $x$ 向 $y$ 连一条权值极大的边,显然这条边永远不会被割,如果选择了 $x$,即割掉 $x$ 与 $t$ 相连的边,那么如果不选 $y$,即割掉 $y$ 与 $s$ 相连的边,就会出现路径 $s \to x \to y \to t$,所以必须选择 $y$。而如果不选 $x$ 则对 $y$ 的选择没有影响。
至此,问题符合使用 Dinic 算法解决网络流的条件,结合最大流-最小割定理,可以使用 Dinic 算法解决此类问题。
转化
在本题中,吃了每种类型为 $x$ 的寿司需要付出 $x$ 的代价,而吃过类型为 $x$ 的寿司需要付出 $mx^2$ 的代价。考虑将每种 $d_{i,j}$ 的收益看成物品,显然如果选择 $d_{i,j}$($i<j$),则必须选择 $d_{i,j-1}$ 以及 $d_{i+1,j}$。
至此,转化完成,可以用最大权闭合子图的模型求解。
namespace LZX
{
using namespace std;
typedef long long i64;
const int MAXN=6060,MAXM=16060;
const i64 INF=0x7fffffffffffffff;
int s,t,cnt=1,head[MAXN],to[MAXM<<1],nxt[MAXM<<1],pre[MAXN],dep[MAXN],d[105][105],id[105][105],a[105];
i64 f[MAXM<<1];
void g_flow_add(int a,int b,i64 c)
{
nxt[++cnt]=head[a];
head[a]=cnt;
to[cnt]=b;
f[cnt]=c;
nxt[++cnt]=head[b];
head[b]=cnt;
to[cnt]=a;
f[cnt]=0;
}
bool g_flow_BFS()
{
int u,v;
queue<int> q;
memset(dep,0,sizeof(dep));
dep[s]=1;
q.push(s);
do
{
u=q.front();
q.pop();
for(int i=head[u];i;i=nxt[i])
{
v=to[i];
if(f[i]&&!dep[v])
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
while(!q.empty());
return dep[t];
}
i64 g_flow_DFS(int u,i64 flow)
{
i64 res,v,temp;
if(u==t)
{
return flow;
}
res=0;
for(int &i=pre[u];i;i=nxt[i])
{
v=to[i];
if(f[i]&&dep[v]==dep[u]+1)
{
temp=g_flow_DFS(v,min(flow,f[i]));
f[i]-=temp;
f[i^1]+=temp;
flow-=temp;
res+=temp;
if(!flow)
{
break;
}
}
}
return res;
}
i64 g_flow_dinic()
{
i64 res=0;
while(g_flow_BFS())
{
memmove(pre,head,sizeof(head));
res+=g_flow_DFS(s,INF);
}
return res;
}
int _main()
{
int n,m,k,maxa,cost;
i64 ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",a+i);
maxa=max(maxa,a[i]);
}
s=1;
t=2;
k=2;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
scanf("%d",&d[i][j]);
id[i][j]=++k;
}
}
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
cost=d[i][j];
if(i==j)
{
if(m)
{
g_flow_add(id[i][j],a[i]+k,INF);
}
cost-=a[i];
}
else
{
g_flow_add(id[i][j],id[i+1][j],INF);
g_flow_add(id[i][j],id[i][j-1],INF);
}
if(cost>0)
{
g_flow_add(s,id[i][j],cost);
ans+=1ll*cost;
}
else if(cost<0)
{
g_flow_add(id[i][j],t,-cost);
}
}
}
if(m)
{
for(int i=1;i<=maxa;i++)
{
g_flow_add(++k,2,i*i);
}
}
printf("%lld\n",ans-g_flow_dinic());
return 0;
}
}

浙公网安备 33010602011771号