首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

CF 237E(字母拣选-费用流)

2012-11-08 
CF 237E(字母选取-费用流)题目大意:有一字符串S,你需要从n个字符串中选取一些来拼出这个串,第i个字符串代

CF 237E(字母选取-费用流)

题目大意:有一字符串S,你需要从n个字符串中选取一些来拼出这个串,第i个字符串代价为i,限制取P次,问最小代价(无解输出-1)


建立超源S=0,超汇T=n+26+1 

1-n的结点为字符串 n+1-n+26的结点为字符

则可得——————————————————

从S向字符串连(最多可取数量),费用为i

从字符向T连(欲取数量)

从字符串向字符连(字符串可取该字母的数量)

得到图

跑费用……


!负数的布尔值为1.


#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<string>#include<algorithm>#include<functional>#include<iostream>using namespace std;#define MAXN (200+10)#define M26 100#define A 96#define NONE (2139062143)int map[MAXN][MAXN]={0},cost[MAXN][MAXN]={0},stf[M26]={0};int start=0,end,n;char s[5000];int d[MAXN],pre[MAXN],q[MAXN*8];bool b[MAXN];void spfa(){memset(b,0,sizeof(b));memset(d,127,sizeof(d));memset(q,0,sizeof(q));memset(pre,0,sizeof(pre));int head=1,tail=1;q[1]=start;b[start]=1;d[start]=0;while (head<=tail){int now=q[head];for (int i=0;i<=end;i++)if (map[now][i]>0&&d[now]+cost[now][i]<d[i]){d[i]=d[now]+cost[now][i];pre[i]=now;if (!b[i]){q[++tail]=i;b[i]=1;}}b[now]=0;head++;}}void hllp(){int totalcost=0;while (1){spfa();if (d[end]==NONE) break;int flow=NONE,i=end;do{flow=min(flow,map[pre[i]][i]);i=pre[i];}while (i!=start);i=end;do{totalcost+=flow*cost[pre[i]][i];map[pre[i]][i]-=flow;map[i][pre[i]]+=flow;i=pre[i];}while (i!=start);}for (int i=end-27;i<end;i++)if (map[i][end]) {cout<<"-1\n";return;}cout<<totalcost<<endl;}int main(){//freopen("c.in","r",stdin);scanf("%s",s);scanf("%d",&n);int len=strlen(s);for (int i=0;i<len;i++) stf[s[i]-A]++;end=n+27;for (int i=1;i<=26;i++) map[n+i][end]=stf[i];for (int i=1;i<=n;i++){scanf("%s",s);scanf("%d",&map[start][i]);memset(stf,0,sizeof(stf));for (int j=0;j<strlen(s);j++) stf[s[j]-A]++;for (int j=1;j<=26;j++) map[i][n+j]=stf[j];cost[0][i]=i;cost[i][0]=-cost[0][i];}/*for (int i=0;i<=end;i++)for (int j=0;j<=end;j++)if (map[i][j]) cout<<i<<' '<<j<<' '<<map[i][j]<<endl;*/hllp();cout<<'\n';/*for (int i=0;i<=end;i++)for (int j=0;j<=end;j++)if (map[i][j]) cout<<i<<' '<<j<<' '<<map[i][j]<<endl;*/return 0;}


热点排行