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 }