BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图

Posted fcwww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图相关的知识,希望对你有一定的参考价值。

BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图

题意:http://www.lydsy.com/JudgeOnline/problem.php?id=4873

分析:我们发现分数正负都有,并且之间有依赖关系,很容易想到最大权闭合子图。

建图:

1.S向正点连边,负点向T连边。

2.选了[i~j]显然要选[i+1~j]和[i~j-1],分别连边。

3.对于i==j的点,向对应的寿司连边。

4.总花费m*x*x+c*x拆成两部分。对于每个代号x,向T连容量为m*x*x的边,c*x这部分我们考虑算f[i][i]时把f[i][i]的值减掉x,当然也可以每个寿司向T连容量为x的边。

完了。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 #define inf 100000000
 7 #define LL long long
 8 #define S (30000)
 9 #define T (30001)
10 int d[110][110],n,m;
11 int head[31000],to[4000000],nxt[4000000],cnt=1;
12 int dep[31000],a[110],tot,idx[110][110],mxn;
13 LL flow[4000000],sum;
14 inline void add(int u,int v,LL f)
15 {
16     to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;flow[cnt]=f;
17     to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;flow[cnt]=0;   
18 }
19 bool bfs()
20 {
21     queue <int> q;
22     memset(dep,0,sizeof(dep));
23     dep[S]=1;q.push(S);
24     while(!q.empty())
25     {
26         int x=q.front();q.pop();
27         for(int i=head[x];i;i=nxt[i])
28         {
29             if(!dep[to[i]]&&flow[i])
30             {
31                 dep[to[i]]=dep[x]+1;
32                 if(to[i]==T)return 1;
33                 q.push(to[i]);  
34             }
35         }
36     }
37     return 0;
38 }
39 LL dfs(int x,LL mf)
40 {
41     if(x==T)return mf;
42     LL nf=0;
43     for(int i=head[x];i;i=nxt[i])
44     {
45         if(dep[to[i]]==dep[x]+1&&flow[i])
46         {
47             int tmp=dfs(to[i],min(flow[i],mf-nf));
48             nf+=tmp;
49             flow[i]-=tmp;
50             flow[i^1]+=tmp;
51             if(nf==mf)break;
52         }
53     }
54     dep[x]=0;
55     return nf;
56 }
57 void dinic()
58 {
59     LL f;
60     while(bfs())
61     {
62         while(f=dfs(S,inf))
63             sum-=f; 
64     }
65     printf("%lld",sum);
66 }
67 int main()
68 {
69     register int i,j;
70     scanf("%d%d",&n,&m);
71     for(i=1;i<=n;i++)
72         for(j=i;j<=n;j++)
73             idx[i][j]=++tot;
74     for(i=1;i<=n;i++)scanf("%d",&a[i]),mxn=max(mxn,a[i]);
75     for(i=1;i<=mxn;i++)add(tot+i,T,m*i*i);
76     for(i=1;i<=n;i++)add(idx[i][i],tot+a[i],inf);
77     for(i=1;i<=n;i++)
78     {
79         for(j=i;j<=n;j++)
80         {
81             scanf("%d",&d[i][j]);
82             if(i==j)d[i][j]-=a[i];
83             else{
84                 add(idx[i][j],idx[i+1][j],inf);
85                 add(idx[i][j],idx[i][j-1],inf); 
86             }
87             if(d[i][j]>0)
88             {
89                 sum+=d[i][j];   
90                 add(S,idx[i][j],d[i][j]);
91             }
92             else{
93                 add(idx[i][j],T,-d[i][j]);
94             }
95         }
96     }
97     dinic();
98 }

 

以上是关于BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4873: [Shoi2017]寿司餐厅

BZOJ4873: [Shoi2017]寿司餐厅

BZOJ:4873: [Shoi2017]寿司餐厅

最大权闭合子图bzoj4873: [Shoi2017]寿司餐厅

bzoj4873: [Shoi2017]寿司餐厅(最小割)

bzoj4873: [Shoi2017]寿司餐厅