hdu5772-String problem(最大权闭合子图问题)
解析:
多校标答
第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得分)
第二类:原串中的n个点每个点拆出一个点,第i个点权值为 –a[s[i]] (表示要花费)
第三类:对于10种字符拆出10个点,每个点的权值为 -(b[x]-a[x])
最大权闭合图用网络流求解,根据原图建立一个等价的网络,构建规则如下。
对于点权为正的节点,从源点连一条容量为点权的边到该点,对于点权为负的边,从该点连一条容量为点权绝对值的边到汇点。原图中的边保留,容量为inf。最大权值即为图中所有正点权之和减去最大流。
这题我看了半天才理解。。。。。
代码
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int INF=1e9+;
const int maxn=;
const int maxnode=maxn*maxn;
int N,a[],b[],w[maxn][maxn];
int eid,S,T; //eid用于边的编号,S,T分别为源点汇点
vector<int> G[maxnode]; //存储边的编号
struct edge
{
int u,v,cap,flow; //头,尾,容量和流量
edge(int u=,int v=,int cap=,int flow=):u(u),v(v),cap(cap),flow(flow){}
}E[maxnode*];
void AddEdge(int u,int v,int c) //建边
{
E[eid]=edge(u,v,c,); //正向边
G[u].push_back(eid); eid++;
E[eid]=edge(v,u,,); //反向边
G[v].push_back(eid); eid++;
}
bool vis[maxnode];
int d[maxnode],cur[maxnode];
queue<int> que;
bool BFS()
{
memset(vis,false,sizeof(vis));
while(!que.empty()) que.pop();
vis[S]=true;
d[S]=;
que.push(S);
while(!que.empty())
{
int u=que.front(); que.pop();
int Size=G[u].size();
for(int i=;i<Size;i++)
{
int id=G[u][i];
edge& e=E[id];
int v=e.v;
if(!vis[v]&&e.cap>e.flow)
{
vis[v]=true;
d[v]=d[u]+;
que.push(v);
}
}
}
return vis[T];
}
int DFS(int u,int a) //分层
{
if(u==T||a==) return a;
int ret=,f;
int Size=G[u].size();
for(int& i=cur[u];i<Size;i++)
{
int id=G[u][i];
edge& e=E[id];
int v=e.v;
if(d[u]+==d[v]&&(f=DFS(v,min(a,e.cap-e.flow)))>)
{
ret+=f;
e.flow+=f;
E[id^].flow-=f;
a-=f;
if(a==) break;
}
}
return ret;
}
int MaxFlow(int s,int t) //最大流Dinic算法
{
S=s; T=t;
int ret=;
while(BFS())
{
memset(cur,false,sizeof(cur));
ret+=DFS(S,INF);
}
return ret;
}
int main()
{
int TT,Case=;
scanf("%d",&TT);
while(TT--)
{
char SS[maxn];
scanf("%d",&N);
scanf("%s",SS);
for(int i=;i<;i++) scanf("%d%d",&a[i],&b[i]);
int be=N*N+N+;
int en=be+;
for(int i=;i<=en;i++) G[i].clear(); eid=;
int ans=;
for(int i=;i<N;i++)
for(int j=;j<N;j++)
{
scanf("%d",&w[i][j]);
if(i==j) continue;
ans+=w[i][j];
AddEdge(be,i*N+j,w[i][j]);
AddEdge(i*N+j,N*N+i,INF);
AddEdge(i*N+j,N*N+j,INF);
}
for(int i=;i<N;i++) AddEdge(N*N+i,N*N+N+SS[i]-'',INF);
for(int i=;i<N;i++) AddEdge(N*N+i,en,a[SS[i]-'']);
for(int i=;i<;i++) AddEdge(N*N+N+i,en,b[i]-a[i]);
printf("Case #%d: %d\n",++Case,ans-MaxFlow(be,en));
}
return ;
}
hdu5772-String problem(最大权闭合子图问题)的更多相关文章
- hdu 5772 String problem 最大权闭合子图
String problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5772 Description This is a simple pro ...
- 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个点每个 ...
- HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4971 Description There's a company with several ...
- b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子图
b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子 题意:n*m个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...
- BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图
BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图 题意:http://www.lydsy.com/JudgeOnline/problem.php?id=4873 分析:我们发现分数正负 ...
- Petya and Graph(最小割,最大权闭合子图)
Petya and Graph http://codeforces.com/contest/1082/problem/G time limit per test 2 seconds memory li ...
- HDU5772 String problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission ...
- BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...
随机推荐
- MyBatis映射文件的resultMap如何做表关联
MyBatis的核心是其映射文件,SqlMap文件,里面配置了项目中用到了什么SQL语句,和数据库相关的逻辑都在这个映射文件里.顾名思义,映射文件就是对Java对象和SQL的映射.这里简单介绍一下映射 ...
- c++命名空间瀑布
一般情况,函数放在命名空间外,命名空间内部放置声明 #include<iostream> using namespace std; //一般情况,函数放在命名空间外,命名空间内部放置声明 ...
- [iOS] Create TableView & customize UITableViewCell
1. First artical, notice the last thing - Connecting the DataSource and Delegate: http://www.appcoda ...
- Fragment的简单使用
最近一直有点忙,刚刚看到一个朋友的留言提到Fragment中加载ListView的问题,这里写了一个非常简单的测试,至于对Fragment的增.删.改实现动态布局构建灵活的UI,以后有时间在讨论: M ...
- IOS深入学习(9)之Objective-C
1 前言 今天我们来解除一篇有关Objective-C的介绍文章,详情如下. 原文链接:http://blog.csdn.net/developer_zhang/article/details/120 ...
- mysql 主从复制配置步骤
1.准备两台数据库环境,或者单台多实例环境,能否正常启动和登录. 2.配置my.cnf文件,主库配置log-bin和server-id参数,从库配置server-id,不能和主库及其他从库一样,一般不 ...
- SQL中@@ROWCOUNT函数
返回受上一语句影响的行数.如果行数大于 20 亿,请使用 ROWCOUNT_BIG. 语法 @@ROWCOUNT 返回类型 int 注释 Transact-SQL 语句可以通过下列方 ...
- 私人C#笔记
coust 定义常量 string是密封类,所以不能继承它 namespace默认是按照文件夹的结构命名的,如(System.文件夹.子文件夹),而且namespace是可以手动改的 Arra ...
- QQ在线联系代码
添加图文模块,标题地址:tencent://message/?uin=你的QQ号&Site=myqq&Menu=yes "你的QQ号"就写您自己的Q号 图片地址写: ...
- AngularJs练习Demo9 Http
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...