• [bzoj4873]寿司餐厅


    首先注意题目中的一些细节问题:1.同一个区间不能累加;2.每一种寿司才能提供$x$的代价;3.每一种代号的寿司才能贡献$mx^{2}$的代价
    这些就很好的为最小割提供了条件,考虑最大权闭合子图的建图:
    1.$(S,id(i,j),d[i][j])(d[i][j]ge 0)$,$(id(i,j),T,-d[i][j])(d[i][j]<0)$,先将所有大于等于0的累加起来,然后将不选的切掉
    2.$(id(i,j),id(i,j-1),oo)$,$(id(i,j),id(i-1,j),oo)$,$(id(i,i),id(i),oo)$,表示选这个就要选子区间(不能直接将子区间的收益加到上面,因为细节1)
    3.$(id(i),T,type(id(i)))$,$(type(i),T,mi^{2})$,$(id(i),type(id(i)),oo)$,这些都只需要删掉一次就可以无限选,因为细节2和3
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 20005
     4 #define oo 0x3f3f3f3f
     5 struct ji{
     6     int nex,to,len;
     7 }edge[N<<2];
     8 queue<int>q;
     9 int E,n,m,x,ans,head[N],a[N],vis[N],d[N],work[N];
    10 int id(int x,int y){
    11     return (x-1)*n+y;
    12 }
    13 void add(int x,int y,int z){
    14     edge[E].nex=head[x];
    15     edge[E].to=y;
    16     edge[E].len=z;
    17     head[x]=E++;
    18     if (E&1)add(y,x,0);
    19 }
    20 bool bfs(){
    21     q.push(0);
    22     memset(vis,0,sizeof(vis));
    23     memset(d,0,sizeof(d));
    24     vis[0]=1;
    25     while (!q.empty()){
    26         int k=q.front();
    27         q.pop();
    28         for(int i=head[k];i!=-1;i=edge[i].nex)
    29             if ((edge[i].len)&&(!vis[edge[i].to])){
    30                 vis[edge[i].to]=1;
    31                 q.push(edge[i].to);
    32                 d[edge[i].to]=d[k]+1;
    33             }
    34     }
    35     return d[N-5]>0;
    36 }
    37 int dfs(int k,int s){
    38     if (k==N-5)return s;
    39     for(int &i=work[k];i!=-1;i=edge[i].nex)
    40         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
    41             int p=dfs(edge[i].to,min(s,edge[i].len));
    42             if (p){
    43                 edge[i].len-=p;
    44                 edge[i^1].len+=p;
    45                 return p;
    46             }
    47         }
    48     return 0;
    49 } 
    50 int main(){
    51     scanf("%d%d",&n,&m);
    52     memset(head,-1,sizeof(head));
    53     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    54     for(int i=1;i<=n;i++)
    55         for(int j=i;j<=n;j++){
    56             scanf("%d",&x);
    57             if (x<0)add(id(i,j),N-5,-x);
    58             else{
    59                 ans+=x;
    60                 add(0,id(i,j),x);
    61             }
    62             if (i<n)add(id(i,j),id(i+1,j),oo);
    63             if (j>1)add(id(i,j),id(i,j-1),oo);
    64         }
    65     for(int i=1;i<=n;i++){
    66         add(id(i,i),id(n,n)+i,oo);
    67         add(id(n,n)+i,id(n,n)+n+a[i],oo);
    68         add(id(n,n)+i,N-5,a[i]);
    69     }
    70     for(int i=1;i<=1000;i++)add(id(n,n)+n+i,N-5,i*i*m);
    71     while (bfs()){
    72         memcpy(work,head,sizeof(work));
    73         while (x=dfs(0,oo))ans-=x;
    74     }
    75     printf("%d",ans);
    76 }
    View Code
  • 相关阅读:
    全排列问题(内测第0届第1题)
    提取字符串中的数字(C语言)
    尾递归=递归+迭代?
    Android各版本代号、版本号、API/NDK级别、发布时间及市场份额
    C语言中文件打开模式(r/w/a/r+/w+/a+/rb/wb/ab/rb+/wb+/ab+)浅析
    sizeof既是关键字,又是运算符(操作符),但不是函数!
    探寻main函数的“标准”写法,以及获取main函数的参数、返回值
    Scala比较器:Ordered与Ordering
    【Python实战】Pandas:让你像写SQL一样做数据分析(一)
    【Python实战】Scrapy豌豆荚应用市场爬虫
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13046587.html
Copyright © 2020-2023  润新知