zoukankan      html  css  js  c++  java
  • CF 132E 费用流

    题意:

    题解:

    今天又遇到这个类型的建图题,有没有做出来。

    于是今天总结一下这个题的模型——顶点覆盖(每个顶点恰好覆盖一次)

    先不考虑赋初值的费用:

    考虑赋初值:

    具体做法请参考:http://www.cnblogs.com/proverbs/archive/2013/01/06/2848043.html

    尽管不是一道题目,但是其实思想是一样的,赋初值=瞬移

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 
      6 #define N 2000
      7 #define M 200000
      8 #define INF 1e9
      9 #define BUG system("pause")
     10 
     11 using namespace std;
     12 
     13 int head[N],next[M],to[M],len[M],pr[M];
     14 int dis[N],pre[N],q[M],mlen;
     15 int val[N],sp[N],sb[N];
     16 bool vis[N];
     17 int n,m,T,S,cnt,S1;
     18 
     19 inline void add(int u,int v,int r,int w)
     20 {
     21     to[cnt]=v; len[cnt]=r; pr[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
     22     to[cnt]=u; len[cnt]=0; pr[cnt]=-w; next[cnt]=head[v]; head[v]=cnt++;
     23 }
     24 
     25 inline int cal(int x)
     26 {
     27     int rt=0;
     28     while(x)
     29     {
     30         if(x&1) rt++;
     31         x>>=1;
     32     }
     33     return rt;
     34 }
     35 
     36 inline void read()
     37 {
     38     scanf("%d%d",&n,&m);
     39     for(int i=1;i<=n;i++)
     40     {
     41         scanf("%d",&sp[i]);
     42         val[i]=cal(sp[i]);
     43     }
     44     memset(head,-1,sizeof head); cnt=0;
     45     memset(vis,0,sizeof vis);
     46     S=0,S1=n+n+1; T=S1+1;
     47     add(S,S1,m,0);
     48     for(int i=1;i<=n;i++)
     49     {
     50         add(S1,i+n,1,val[i]);
     51         add(S,i,1,0);
     52         add(i+n,T,1,0);
     53     }
     54     for(int i=1;i<=n;i++)
     55         for(int j=i+1;j<=n;j++)
     56         {
     57             if(sp[j]!=sp[i]) add(i,j+n,1,val[j]);
     58             else add(i,j+n,1,0);
     59         }
     60 }
     61 
     62 inline bool spfa()
     63 {
     64     memset(pre,-1,sizeof pre);
     65     memset(dis,0x3f,sizeof dis);
     66     q[1]=S; vis[S]=true; dis[S]=0;
     67     int h=1,t=2,sta;
     68     while(h<t)
     69     {
     70         sta=q[h++]; vis[sta]=false;
     71         for(int i=head[sta];~i;i=next[i])
     72             if(len[i]&&dis[to[i]]>dis[sta]+pr[i])
     73             {
     74                 dis[to[i]]=dis[sta]+pr[i];
     75                 pre[to[i]]=i;
     76                 if(!vis[to[i]]) vis[to[i]]=true,q[t++]=to[i];
     77             }
     78     }
     79     return pre[T]!=-1;
     80 }
     81 
     82 inline void updata()
     83 {
     84     mlen=INF;
     85     for(int i=pre[T];~i;i=pre[to[i^1]])
     86         mlen=min(mlen,len[i]);
     87     for(int i=pre[T];~i;i=pre[to[i^1]])
     88         len[i]-=mlen,len[i^1]+=mlen;
     89 }
     90 
     91 inline void dfs(int u,int bh)
     92 {
     93     sb[u]=bh;
     94     for(int i=head[u];~i;i=next[i])
     95         if(!(i&1)&&!len[i]&&to[i]!=S)
     96         {
     97             if(pr[i]!=0) vis[to[i]-n]=true;
     98             dfs(to[i]-n,bh);
     99         }
    100 }
    101 
    102 inline void go()
    103 {
    104     int ans=0,h=0,num=0;
    105     while(spfa()) updata(),ans+=mlen*dis[T];
    106     for(int i=head[S1];~i;i=next[i])
    107         if(!(i&1)&&!len[i])
    108         {
    109             vis[to[i]-n]=true;
    110             h++;
    111             dfs(to[i]-n,h);
    112         }
    113     h=0;
    114     for(int i=1;i<=n;i++)
    115         if(vis[i]) h++;
    116     printf("%d %d\n",h+n,ans);
    117     for(int i=1;i<=n;i++)
    118     {
    119         if(vis[i]) printf("%c=%d\n",sb[i]+'a'-1,sp[i]);
    120         printf("print(%c)\n",sb[i]+'a'-1);
    121     }
    122 }
    123 
    124 int main()
    125 {
    126     read();
    127     go();
    128     return 0;
    129 }
  • 相关阅读:
    1082 射击比赛 (20 分)
    1091 N-自守数 (15 分)
    1064 朋友数 (20 分)
    1031 查验身份证 (15 分)
    1028 人口普查 (20 分)
    1059 C语言竞赛 (20 分)
    1083 是否存在相等的差 (20 分)
    1077 互评成绩计算 (20 分)
    792. 高精度减法
    791. 高精度加法
  • 原文地址:https://www.cnblogs.com/proverbs/p/2857814.html
Copyright © 2011-2022 走看看