Codeforces 717G Underfail(最小费用最大流 + AC自动机)
题目
Source
http://codeforces.com/problemset/problem/717/G
Description
You have recently fallen through a hole and, after several hours of unconsciousness, have realized you are in an underground city. On one of your regular, daily walks through the unknown, you have encountered two unusually looking skeletons called Sanz and P’pairus, who decided to accompany you and give you some puzzles for seemingly unknown reasons.
One day, Sanz has created a crossword for you. Not any kind of crossword, but a 1D crossword! You are given m words and a string of length n. You are also given an array p, which designates how much each word is worth — the i-th word is worth pi points. Whenever you find one of the m words in the string, you are given the corresponding number of points. Each position in the crossword can be used at most x times. A certain word can be counted at different places, but you cannot count the same appearance of a word multiple times. If a word is a substring of another word, you can count them both (presuming you haven’t used the positions more than x times).
In order to solve the puzzle, you need to tell Sanz what’s the maximum achievable number of points in the crossword. There is no need to cover all postions, just get the maximal score! Crossword and words contain only lowercase English letters.
Input
The first line of the input contains a single integer n (1 ≤ n ≤ 500) — the length of the crossword. The second line contains the crossword string. The third line contains a single integer m (1 ≤ m ≤ 100) — the number of given words, and next m lines contain description of words: each line will have a string representing a non-empty word (its length doesn't exceed the length of the crossword) and integer pi (0 ≤ pi ≤ 100). Last line of the input will contain x (1 ≤ x ≤ 100) — maximum number of times a position in crossword can be used.
Output
Output single integer — maximum number of points you can get.
Sample Input
6
abacba
2
aba 6
ba 3
3
Sample Output
12
分析
题目大概说给一个主串和几个有价值的模式串,某个模式串与主串匹配就能累加对应的价值,一个模式串可以在多个位置和主串匹配但同一个位置只能一次,此外主串各个字符最多可以用x次,问如何匹配使获得的价值最大。
各个模式串在主串匹配的位置可以用AC自动机找到,而这些位置相当于区间。
其实这题就相当于在一条数轴上选择最大权和的区间,使得各个点被覆盖的区间数不超过x。区间k覆盖问题,POJ3680。。
我都不会建图了。。要注意的是区间要处理成左闭右开形式,不然比如[1,1]这个区间建图就会出现负环了。
代码
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 555
#define MAXM 555*1111 struct Edge{
int u,v,cap,cost,next;
}edge[MAXM];
int head[MAXN];
int NV,NE,vs,vt; void addEdge(int u,int v,int cap,int cost){
edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost;
edge[NE].next=head[v]; head[v]=NE++;
}
bool vis[MAXN];
int d[MAXN],pre[MAXN];
bool SPFA(){
for(int i=0;i<NV;++i){
vis[i]=0;
d[i]=INF;
}
vis[vs]=1;
d[vs]=0;
queue<int> que;
que.push(vs);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap && d[v]>d[u]+edge[i].cost){
d[v]=d[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
vis[u]=0;
}
return d[vt]!=INF;
}
int MCMF(){
int res=0;
while(SPFA()){
int flow=INF,cost=0;
for(int u=vt; u!=vs; u=edge[pre[u]].u){
flow=min(flow,edge[pre[u]].cap);
}
for(int u=vt; u!=vs; u=edge[pre[u]].u){
edge[pre[u]].cap-=flow;
edge[pre[u]^1].cap+=flow;
cost+=flow*edge[pre[u]].cost;
}
res+=cost;
}
return res;
} int tn,ch[55500][26],fail[55500];
vector<int> vec[55500];
void insert(char *s,int k){
int x=0;
for(int i=0; s[i]; ++i){
int y=s[i]-'a';
if(ch[x][y]==0) ch[x][y]=++tn;
x=ch[x][y];
}
vec[x].push_back(k);
}
void getfail(){
queue<int> que;
for(int i=0; i<26; ++i){
if(ch[0][i]) que.push(ch[0][i]);
}
while(!que.empty()){
int x=que.front(); que.pop();
for(int i=0; i<26; ++i){
if(ch[x][i]){
fail[ch[x][i]]=ch[fail[x]][i];
que.push(ch[x][i]);
}else ch[x][i]=ch[fail[x]][i];
}
}
} int val[111],len[111];
void ac(char *s){
int x=0;
for(int i=0; s[i]; ++i){
int y=s[i]-'a';
x=ch[x][y];
for(int tmp=x; tmp; tmp=fail[tmp]){
for(int j=0; j<vec[tmp].size(); ++j){
int k=vec[tmp][j];
addEdge(i-len[k]+1,i+1,1,-val[k]);
}
}
}
} char S[555],T[555];
int main(){
int n,m,x;
scanf("%d%s%d",&n,S,&m);
for(int i=1; i<=m; ++i){
scanf("%s%d",T,val+i);
len[i]=strlen(T);
insert(T,i);
}
scanf("%d",&x); vs=n+1; vt=vs+1; NV=vt+1; NE=0;
memset(head,-1,sizeof(head));
addEdge(vs,0,x,0);
addEdge(n,vt,x,0);
for(int i=1; i<=n; ++i){
addEdge(i-1,i,INF,0);
} getfail();
ac(S); printf("%d",-MCMF());
return 0;
}
Codeforces 717G Underfail(最小费用最大流 + AC自动机)的更多相关文章
- HDU1853 Cyclic Tour(最小费用最大流)
题目大概说给一张有向图,每条边都有权值,要选若干条边使其形成若干个环且图上各个点都属于且只属于其中一个环,问选的边的最少权值和是多少. 各点出度=入度=1的图是若干个环,考虑用最小费用最大流: 每个点 ...
- 最小费用最大流 POJ2195-Going Home
网络流相关知识参考: http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html 出处:優YoU http://blog.csdn. ...
- 网络流(最小费用最大流):POJ 2135 Farm Tour
Farm Tour Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: ...
- poj_2195Going Home(最小费用最大流)
poj_2195Going Home(最小费用最大流) 标签: 最小费用最大流 题目链接 题意: 有n*m的矩阵,H表示这个点是一个房子,m表示这个点是一个人,现在每一个人需要走入一个房间,已经知道的 ...
- Luogu--3381 【模板】最小费用最大流
题目链接 3381 [模板]最小费用最大流 手写堆版本 dijkstra 400+ms 看来优先队列的常数好大 #include<bits/stdc++.h> using namesp ...
- Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)
Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...
- Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)
Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...
- HDU5988/nowcoder 207G - Coding Contest - [最小费用最大流]
题目链接:https://www.nowcoder.com/acm/contest/207/G 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 ...
- nowcoder 206A - Birthday - [最小费用最大流]
题目链接:https://www.nowcoder.com/acm/contest/206/A 题目描述 恬恬的生日临近了.宇扬给她准备了一个蛋糕.正如往常一样,宇扬在蛋糕上插了n支蜡烛,并把蛋糕分为 ...
随机推荐
- 非常提高mac生产力的一些插件归纳整理
1.cheatsheet 快捷键提示插件,下载后按command键3秒,可以显示当前app的所有快捷键. 比如我现在在chrome的界面,按下command三秒,会弹出一个快捷键提示框. 2.Ba ...
- Java开发11个过不去的梗
现在随着编程的普及,作为java程序猿开发的过程逐渐的受到领导的重视,无论自己的经理是能看懂,还是不能看懂,一些事项必须注意起来,不要让自己将来处于不尴不尬的境地,当然这样也方便你我他 1.不在属性文 ...
- 电商总结(五)移动M站建设
最近在一直在搞M站,也就是移动web站点.由于是第一次,也遇到了很多问题,所以把最近了解到的东西总结总结.聊一聊什么是移动M站,它有啥作用和优势. 也有人会问,M站和APP有什么不同? 1. APP ...
- maven install Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.1.1:war (default-war) on project web_nanchang
maven打包成war时,报错:Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.1.1:war (default- ...
- Java表格的简单使用一
JTable组件使用的是模型/视图/控制器的设计方式,将可视化组件从其数据中分离出来,因此表格中的数据都封装在数据模型中.其中最重要的支持类就是TableModel类,这个类用来定义JTable类以及 ...
- Idea 开发 web项目
1.经历 很久没有搞 web 项目了,最近一段时间搞过很多次了,但是总是在 mac 上部署失败. 2.方法: 用idea 新建一个模板的 Spring MVC 项目,部署就可以了. 3.参考: htt ...
- Daily Scrum Meeting ——TenthDay
一.Daily Scrum Meeting照片 二.Burndown Chart 新增了几个issues 三.项目进展 1.完成了登录界面与管理员和发布者界面的整合. 2.活动发布者界面的完成 四.问 ...
- Alpha版本十天冲刺——Day 10
站立式会议 最后一天,很高兴我们做出了跟预期差不多的版本,实现了基本功能,虽然还有一些bug,但是下一阶段我们会继续加油! 会议总结 队员 今天完成 遇到的问题 感想 鲍亮 功能细节更改 我的手机运行 ...
- OpenVPN使用用户名/密码验证方式
OpenVPN推荐使用证书进行认证,安全性很高,但是配置起来很麻烦.还好它也能像pptp等vpn一样使用用户名/密码进行认证. 不管何种认证方式,服务端的ca.crt, server.crt, ser ...
- yii2事务运用举例
直接上代码: $db = Yii::$app->db; $transaction = $db->beginTransaction(); //开启事务 try { // 更新member表 ...