【HDU5772】String Problem [网络流]
String Problem
Time Limit: 10 Sec Memory Limit: 64 MB
[Submit][Status][Discuss]
Description

Input

Output

Sample Input
1
3
135
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2
0 0 3
1 0 0
4 0 0
Sample Output
3
HINT

Solution
官方题解:
首先将点分为3类
第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得到的价值)
第二类:原串中的n个点每个点拆出一个点,第i个点权值为 –a[s[i]] (表示需要的花费)
第三类:对于10种字符拆出10个点,每个点的权值为 -(b[x]-a[x])
那么我们可以得到一个关系图 ,对于第一类中的点Pij,如果想要选择Pij,你就必须要选中第二类中的点i和j,对于第二类中的点如果你想选中第i个点,其对应的字符s[i],那么就必须选中第三类中s[i] 对应的点,因为每个种类的点第一次选中时花费是b[s[i]],而第二类中花费都是a[s[i]],一定要补上b[s[i]]-a[s[i]],而且只需要补上一次。
得到上面的关系图后然后就是普通的最大权闭合子图问题,直接求解即可。
然后我们得到了若干关系,直接建边跑一边网络流即可。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
using namespace std; const int ONE = ;
const int POI = ;
const int INF = ; int Q,n;
int S,T;
char s[];
int Val[][];
int next[ONE],first[POI],go[ONE],w[ONE],tot;
int Dep[POI],q[ONE],E[POI],tou,wei;
int part1,part2,part3;
int Ans; struct power
{
int a,b;
}a[]; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} void Add(int u,int v,int z)
{
next[++tot]=first[u]; first[u]=tot; go[tot]=v; w[tot]=z;
next[++tot]=first[v]; first[v]=tot; go[tot]=u; w[tot]=;
} int Bfs()
{
memset(Dep,,sizeof(Dep));
tou=; wei=;
q[]=S; Dep[S]=;
for(int i=S;i<=T;i++) E[i]=first[i];
while(tou<wei)
{
int u=q[++tou];
for(int e=first[u];e;e=next[e])
{
int v=go[e];
if(Dep[v] || !w[e]) continue;
Dep[v]=Dep[u]+;
q[++wei]=v;
}
}
return (Dep[T]>);
} int Dfs(int u,int Limit)
{
if(u==T || !Limit) return Limit;
int from=,f;
for(int &e=E[u];e;e=next[e])
{
int v=go[e];
if(Dep[v]!=Dep[u]+ || !w[e]) continue;
f=Dfs(v,min(Limit,w[e]));
w[e]-=f;
w[((e-)^)+]+=f;
Limit-=f;
from+=f;
if(!Limit) break;
}
return from;
} void Solve()
{
Ans = tot = ;
memset(first,,sizeof(first));
n=get();
scanf("%s",s+);
for(int i=;i<;i++)
a[i].a=get(), a[i].b=get();
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
Val[i][j]=get(); part1 = n*(n-)/; part2 = n; part3 = ;
S=; T= part1 + part2 + part3 +;
int num = ;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
num ++; Ans += Val[i][j]+Val[j][i];
Add(S,num, Val[i][j]+Val[j][i]);
Add(num,part1+i, INF);
Add(num,part1+j, INF);
} for(int i=;i<=n;i++)
{
Add(part1+i,T, a[s[i]-''].a);
Add(part1+i,part1+part2+s[i]-''+, INF);
} for(int i=;i<;i++)
Add(part1+part2+i+,T, a[i].b-a[i].a); while(Bfs()) Ans-=Dfs(S,INF); printf("%d\n",Ans);
} int main()
{
Q=get();
while(Q--)
Solve();
}
【HDU5772】String Problem [网络流]的更多相关文章
- HDU5772 String problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission ...
- HDU5772 String problem 最大权闭合图+巧妙建图
题意:自己看吧(不是很好说) 分析: 网络流:最大权闭合子图. 思路如下: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得 ...
- HDU5772 String problem(最大权闭合子图)
题目..说了很多东西 官方题解是这么说的: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得分) 第二类:原串中的n个点每个 ...
- hdu 5772 String problem 最大权闭合子图
String problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5772 Description This is a simple pro ...
- hdu String Problem(最小表示法入门题)
hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include &l ...
- HDU 3374 String Problem(KMP+最大/最小表示)
String Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- 【HDU3374】 String Problem (最小最大表示法+KMP)
String Problem Description Give you a string with length N, you can generate N strings by left shift ...
- HDOJ3374 String Problem 【KMP】+【最小表示法】
String Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- HDU 3374 String Problem (KMP+最大最小表示)
HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others) Memory ...
随机推荐
- SQL - SELECT COUNT用法
SQL Server数据库 COUNT() 函数返回匹配指定条件的行数. 语法 SQL COUNT(column_name) 语法 COUNT(column_name) 函数返回指定列 ...
- 复合类型的声明——是int *p还是int* p
我们先来看一条基本类型的声明语句:int a, b, ... 即一条声明语句由一个数据类型(int)和紧随其后的一个变量名列表(a, b, ...)组成 更通用的描述是:一个基本数据类型和紧随其后的一 ...
- lintcode-135-数字组合
135-数字组合 给出一组候选数字(C)和目标数字(T),找到C中所有的组合,使找出的数字和为T.C中的数字可以无限制重复被选取. 例如,给出候选数组[2,3,6,7]和目标数字7,所求的解为: [7 ...
- lintcode-106-排序列表转换为二分查找树
106-排序列表转换为二分查找树 给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树 样例 标签 递归 链表 思路 类似于二分查找,每次将链表二分,中间节点作为根节点,在建立左子树 ...
- 201621044079WEEK06-接口、内部类
作业06-接口.内部类 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多 ...
- 修改虚拟机上Linux系统的IP地址
然后再输入:ifconfig eth0 192.168.11.6 netmask 255.255.255.0 . 这样就可以把网卡eth0的IP地址修改为 192.168.11.6
- LevelDB速记
LevelDb的基本结构如下: 由六大部分组成: 一.MemTable,用户写入和读取的直接对象, 二.Immutable MemTable,用户状态写入的对象写满的MemTable之后会转为Immu ...
- JDBC连接数据库的过程
以连接MySQL为例: (1)加载MySQL数据库连接的驱动程序.到MySQL官网下载该驱动程序jar包,然后把包复制到WEB-INF/lib目录下,则JDBC会调用Class.forName()方法 ...
- [BZOJ4212]神牛的养成计划
[BZOJ4212]神牛的养成计划 试题描述 Hzwer 成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神 ...
- [POJ 1204]Word Puzzles(Trie树暴搜&AC自己主动机)
Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...