• Codeforces 237E Build String


    比较裸的费用流吧。(刚好把板子打了一遍)

    源点向每个字符连边,流量为要构造的字符串的字符个数,费用为0。

    每个字符向每个字符串连边,流量为这个字符串中这个字符出现的次数,费用为i。

    每个字符串向汇点连边,流量为每个字符串的限制,费用为0。

    然后跑费用流,判断是否满流,如果不是就无解,是就输出花费。

    #include<cstdio>  
    #include<cstring>
    #define S 0
    #define T 500
    struct edge{  
        int to,cap,rev,nx,we;  
    }G[40050];  
    int n,p,ans=0;  
    int h[550],q[40050],d[550];  
    bool mark[550];
    char s[201];
    int cnt1[201],cnt[201][27],lim[201];
    int Min(int a,int b){return a<b?a:b;}  
    void ae(int s,int e,int c,int w){  
        G[++p]=(edge){e,c,p+1,h[s],w};h[s]=p;  
        G[++p]=(edge){s,0,p-1,h[e],-w};h[e]=p;  
    }  
    bool spfa(){  
        memset(d,127/3,sizeof(d));  
        memset(mark,0,sizeof(mark));  
        d[T]=0;mark[T]=1;  
        int head=0,tail=0;  
        int inf=d[0];  
        q[tail++]=T;  
        while(head!=tail){  
            int fr=q[head++];  
            for(int i=h[fr];i;i=G[i].nx){  
                if(G[G[i].rev].cap>0&&d[G[i].to]>d[fr]+G[G[i].rev].we){  
                    d[G[i].to]=d[fr]+G[G[i].rev].we;  
                    if(!mark[G[i].to])mark[G[i].to]=1,q[tail++]=G[i].to;  
                }  
            }  
            mark[fr]=0;  
        }  
        return !(d[0]==inf);  
    }  
    int dfs(int s,int t,int f){  
        mark[s]=1;  
        if(s==t) return f;  
        int sum=0;  
        for(int i=h[s];i;i=G[i].nx){  
            if(G[i].cap>0&&!mark[G[i].to]&&d[s]-G[i].we==d[G[i].to]){  
                int d=dfs(G[i].to,t,Min(G[i].cap,f));  
                if(d)sum+=d,f-=d,G[i].cap-=d,G[G[i].rev].cap+=d;  
                if(f==0)return sum;  
            }  
        }  
        return sum;  
    }  
    int m__f(){  
        int sum=0;  
        while(spfa()){  
            mark[T]=1;  
            while(mark[T]){  
                memset(mark,0,sizeof(mark));
                int tmp=dfs(S,T,99999999);
                sum+=tmp*d[0];  
                ans+=tmp;
            }
        }
        return sum;
    }
    int main(){
        scanf("%s",s);
        int len=strlen(s);
        for(int i=0;i<len;i++){
            cnt1[s[i]-'a'+1]++;
        }
        for(int i=1;i<=26;i++){
          if(cnt1[i]) ae(S,i,cnt1[i],0);
        }
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
          scanf("%s%d",s,&lim[i]);
          for(int j=0;j<strlen(s);j++){
              cnt[i][s[j]-'a'+1]++;
          }
        }
        for(int i=1;i<=n;i++){
          for(int j=1;j<=26;j++){
              if(cnt[i][j]) ae(j,i+26,cnt[i][j],i);
          }
          ae(i+26,T,lim[i],0);
        }
        int cos=m__f();
        if(ans!=len) puts("-1");
        else printf("%d
    ",cos);
        return 0;
    }
  • 相关阅读:
    数据结构与算法(15)——冒泡法和选择法排序
    数据结构与算法(14)——二分查找算法
    数据结构与算法(13)—顺序查找法
    数据结构与算法(12)——动态规划案例
    Object Detection的一些进展(Valse2020.4.30)
    机器学习(1)——模型评估与选择
    数据结构与算法(12)—分治策略
    数据结构与算法(11)—递归
    数据结构与算法(10)——有序表OrderedList
    数据结构与算法(9)——无序表List
  • 原文地址:https://www.cnblogs.com/nzher/p/7424708.html
Copyright © 2020-2023  润新知