zoukankan      html  css  js  c++  java
  • 2016 Multi-University Training Contest 4 T9

    http://acm.hdu.edu.cn/showproblem.php?pid=5772

    最大权闭合子图。

    得到价值w[i][j]的条件是选了i,j这两个位置的字符。选择位置的i字符花费为

    第一次选s[i]:a[s[i]]       不是第一次选s[i]:b[s[i]]

    所以对于选i位置字符前提为选了花费为b[s[i]]-a[s[i]]的字符i。

    得到上面的关系图后然后就是普通的最大权闭合子图问题,直接求解即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define M 120010
     4 #define N 6010
     5 #define inf 1000000000 
     6 int len[M <<1],e[M <<1],nex[M <<1],other[M <<1],head[N],last[N],d[N],num[N];
     7 int te,sum,_,j,num1,num2,w[110][110],a[11],b[11],m,n,i,ans,tot,ss,tt,ee,u,v,c;
     8 char s[110];
     9 int init()
    10 {
    11     memset(head,0,sizeof(head));
    12     memset(num,0,sizeof(num));
    13     memset(d,0,sizeof(d));
    14     ans=ee=0;
    15 }
    16 int min(int a,int b)
    17 {
    18     return a<b?a:b;
    19 }
    20 void add(int u,int v,int c)
    21 {
    22     //printf("%d %d %d
    ",u,v,c);
    23     other[++ee]=ee+1;
    24     e[ee]=v;nex[ee]=head[u];head[u]=ee;len[ee]=c;
    25     other[++ee]=ee-1;
    26     e[ee]=u;nex[ee]=head[v];head[v]=ee;len[ee]=0;
    27 }
    28 int dfs(int x,int flow)
    29 {
    30     int rec,j,p;
    31     if (x==tt) return flow;
    32     rec=0;j=last[x];
    33     while (j!=0)
    34     {
    35         if (len[j]>0 && d[x]==d[e[j]]+1)
    36         {
    37             last[x]=j;
    38             p=dfs(e[j],min(len[j],flow-rec));
    39             len[j]-=p;len[other[j]]+=p;
    40             rec+=p;
    41             if (rec==flow) return rec;
    42         }
    43     j=nex[j];
    44     }
    45     if (d[ss]>tot) return rec;
    46      if (--num[d[x]]==0) d[ss]=tot;
    47      last[x]=head[x];
    48      num[++d[x]]++;
    49      return rec;
    50 }
    51 int main()
    52 {
    53     scanf("%d",&_);
    54     while (_--)
    55     {
    56         sum=0;init();
    57         scanf("%d",&n);
    58         scanf("%s",s+1);
    59         for (i=0;i<=9;i++)
    60             scanf("%d%d",&a[i],&b[i]);
    61         for (i=1;i<=n;i++)
    62             for (j=1;j<=n;j++)
    63                 scanf("%d",&w[i][j]);
    64         num1=1;ss=1;
    65         for (i=1;i<=n;i++)
    66             for (j=i+1;j<=n;j++)
    67                 if (w[i][j]+w[j][i]!=0)
    68                 {
    69                     add(ss,++num1,w[i][j]+w[j][i]);
    70                     sum+=w[i][j]+w[j][i];
    71                 }
    72         num2=1;tt=num1+n+11;
    73         for (i=1;i<=n;i++)
    74             for (j=i+1;j<=n;j++)
    75                    if (w[i][j]+w[j][i]!=0)
    76                   {
    77                     add(++num2,num1+i,inf);
    78                     add(num2,num1+j,inf);
    79                 }
    80         for (i=1;i<=n;i++)
    81         {
    82             add(num1+i,num1+n+s[i]-'0'+1,inf);
    83             add(num1+i,tt,a[s[i]-'0']);
    84         }
    85         for (i=0;i<=9;i++)
    86             add(num1+n+i+1,tt,b[i]-a[i]);
    87         tot=num[0]=tt;
    88         for (i=ss;i<=tt;i++)
    89             last[i]=head[i];
    90         while (d[ss]<tot)
    91             ans+=dfs(ss,2147483647);
    92         printf("Case #%d: %d
    ",++te,sum-ans);
    93     }
    94     return 0;
    95     
    96 }
    View Code
    Run ID Submit Time Judge Status Pro.ID Exe.Time Exe.Memory Code Len. Language Author
    17819971 2016-07-29 15:40:45 Accepted 5772 15MS 2052K 2416 B G++ lbz007
    ------------------------------------------------------------------------- 花有重开日,人无再少年
  • 相关阅读:
    vagrant创建centos7后虚拟机磁盘爆满
    Linuxpython删除某个目录文件夹及文件的方法
    Oracle 中常用查询用户、角色、权限等SQL
    log4j2 rce几个疑惑点解惑
    2021年总结和反思
    使用grep命令,玩转代码审计寻找Sink
    VSCode使用技巧
    [转载]什么是电源的纹波,如何测量它的值,又如何抑制呢?
    【Bug system】GCC Bugzilla
    .net core3.1开始页面实时编译
  • 原文地址:https://www.cnblogs.com/lbz007oi/p/5718783.html
Copyright © 2011-2022 走看看