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


    4873: [Shoi2017]寿司餐厅

    大难题啊啊!!!

    题目:传送门

    题解:一眼题是网络流,但还是不会OTZ,菜啊...

        %题解...

       最大权闭合子图!!!

       好的...开始花式建边:

       1、对于每个区间,我们把它看成一个点,按照权值正负连接源点或汇点(最大权闭合子图的套路)

         2、对于所有的寿司类型k[i],各自开一个点,向ed连边,流量为m*k[i]*k[i];

         3、对于1~n的每个寿司,向它的所属类型连边,流量为无限大;再向ed连边,流量为e[i]。

         4、对于所有的区间i~j,向(i+1,j)和(i,j-1)连边,因为区间具有包含性。

         WA了...再%题解...

         漏了第五种情况:

         5、对于所有区间,向区间内所有的点连边,流量为无限大,表示必须选对应的寿司才能选这个区间QWQ 

           跑网络流。。。

    蒟蒻的代码(丑的一匹,慎点):

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define qread(x)x=read();
      7 using namespace std;
      8 typedef long long LL;
      9 inline int read()
     10 {
     11     int f=1,x=0;char ch;
     12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     14     return f*x;
     15 }
     16 struct node
     17 {
     18     int x,y,c,next,other;
     19 }a[2110000];int last[1110000],len;
     20 int st,ed,n,m;
     21 void ins(int x,int y,int c)
     22 {
     23     int k1,k2;
     24     len++;k1=len;
     25     a[len].x=x;a[len].y=y;a[len].c=c;
     26     a[len].next=last[x];last[x]=len;
     27     
     28     len++;k2=len;
     29     a[len].x=y;a[len].y=x;a[len].c=0;
     30     a[len].next=last[y];last[y]=len;
     31     
     32     a[k1].other=k2;
     33     a[k2].other=k1;
     34 }
     35 int list[11000],h[11000];
     36 int head,tail;
     37 bool bfs()
     38 {
     39     memset(h,0,sizeof(h));h[st]=1;
     40     list[1]=st;head=1;tail=2;
     41     while(head!=tail)
     42     {
     43         int x=list[head];
     44         for(int k=last[x];k;k=a[k].next)
     45         {
     46             int y=a[k].y;
     47             if(h[y]==0 && a[k].c>0)
     48             {
     49                 h[y]=h[x]+1;
     50                 list[tail++]=y;
     51             }
     52         }
     53         head++;
     54     }
     55     if(h[ed]>0)return true;
     56     return false;
     57 }
     58 int findflow(int x,int flow)
     59 {
     60     if(x==ed)return flow;
     61     int s=0,t;
     62     for(int k=last[x];k;k=a[k].next)
     63     {
     64         int y=a[k].y;
     65         if(h[y]==h[x]+1 && a[k].c>0 && flow>s)
     66         {
     67             t=findflow(y,min(a[k].c,flow-s));
     68             s+=t;
     69             a[k].c-=t;a[a[k].other].c+=t;
     70         }
     71     }
     72     if(s==0)h[x]=0;
     73     return s;
     74 }
     75 int e[110];
     76 int d[110][110];
     77 int id1[110][110],id2[1100];
     78 bool v[1100];
     79 int jb()
     80 {
     81     memset(v,false,sizeof(v));
     82     LL sum=0,cnt=0;
     83     for(int i=1;i<=n;i++)    
     84         for(int j=i;j<=n;j++)
     85             id1[i][j]=++cnt;
     86     
     87     for(int i=1;i<=n;i++)
     88         if(v[e[i]]==0)
     89         {
     90             v[e[i]]=true;
     91             id2[e[i]]=++cnt;
     92         }
     93         
     94     ed=cnt+n+1;
     95     memset(v,false,sizeof(v));
     96     for(int i=1;i<=n;i++)
     97         if(v[e[i]]==0)
     98         {
     99             v[e[i]]=true;
    100             ins(id2[e[i]],ed,m*e[i]*e[i]);//种类的花费,和ed连边
    101         }
    102     for(int i=1;i<=n;i++)
    103     {
    104         ins(cnt+i,id2[e[i]],999999999);
    105         ins(cnt+i,ed,e[i]);
    106     }
    107     for(int i=1;i<=n;i++)
    108         for(int j=i;j<=n;j++)
    109         {
    110             if(d[i][j]>0)
    111             {
    112                 sum+=d[i][j];
    113                 ins(st,id1[i][j],d[i][j]);
    114                 ins(id1[i][j],cnt+i,999999999);
    115                 ins(id1[i][j],cnt+j,999999999);
    116             }
    117             else if(d[i][j]<0)
    118             { 
    119                 ins(id1[i][j],ed,-d[i][j]);
    120                 ins(id1[i][j],cnt+i,999999999);
    121                 ins(id1[i][j],cnt+j,999999999);
    122             }
    123             if(i!=j)
    124             {
    125                 ins(id1[i][j],id1[i][j-1],999999999);
    126                 ins(id1[i][j],id1[i+1][j],999999999);
    127             }
    128         }
    129     return sum;
    130 }
    131 int main()
    132 {
    133     qread(n);qread(m);
    134     for(int i=1;i<=n;i++)qread(e[i]);
    135     for(int i=1;i<=n;i++)
    136         for(int j=i;j<=n;j++)
    137             qread(d[i][j]);
    138     st=0;
    139     LL sum=jb();
    140     /*
    141     for(int i=1;i<=len;i++)
    142             if(a[i].x==0)
    143                 printf("%d %d
    ",a[i].y,a[i].c);
    144     printf("
    ");
    145     for(int i=1;i<=len;i++)
    146             if(a[i].y==ed)
    147                 printf("%d %d
    ",a[i].x,a[i].c);
    148     */
    149     int ans=0;
    150     while(bfs())ans+=findflow(st,999999999);
    151     printf("%lld
    ",sum-ans);
    152     return 0;
    153 }
  • 相关阅读:
    Jisa's Notebook
    前端常见跨域解决方案
    串口
    logging的使用
    Hexo
    优美的二维树状数组
    数据结构之树的基本概念
    js 监听ios手机键盘弹起和收起的事件
    jquery.qrcode.js生成二维码(前端生成二维码)
    js产生一个随机的字符串数字组合
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8010634.html
Copyright © 2020-2023  润新知