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 仅包含一个整数,表示可以 ...
随机推荐
- WPF - XAML如何引入名字空间
WPF 的XAML引入名字空间的概念,经常容易让人混淆.如何引入名字空间,并且在XAML中调用其中的类,下面给一个简单的介绍. 比如我们有一个Hepler类. namespace Wheat.PIMS ...
- [RxJS] Toggle A Stream On And Off With RxJS
This lesson covers how to toggle an observable on and off from another observable by showing how to ...
- Oracle—RMAN备份(一)
一.RMAN备份相关概念 1.RMAN备份中表空间不需要处于backup模式下,它备份数据文件,归档日志文件,控制文件,spfile和备份集片,但不备份联机重做日志文件,临时文件和口令文件. 2.备份 ...
- java基础之成员变量与局部变量
成员变量的含义 局部变量的含义 成员变量与局部变量的区别
- C#遍历Object各个属性含List泛型嵌套。
同事遇到一个问题:在做手机app接口时,返回JSON格式,json里面的数据属性均是string类型,但不能出现NULL(手机端那边说处理很麻烦,哎).Model已经创建好了,而且model的每个属性 ...
- 附加到IIS调试出现不会命中断点
当项目附加到IIS进行调试时,如果在IIS中没有配置该项目则在设置断点是会出现:当前不会命中断点 还没有为该文档加载任何符号
- (转)sql server 2008 不允许保存更改,您所做的更改要求删除并重新创建以下表 的解决办法
启动SQL Server 2008 Management Studio 工具菜单----选项----Designers(设计器)----阻止保存要求重新创建表的更改 取消勾选即可.
- Maybe I go too extreme
昨天拖着一个没睡好的身体去面试了2家公司 被问到Collection的子集的时候顿时傻了一会,明明很简单的问题一时就想不起来了,哈哈.果然做it的人身体要顾好,状态太差了. 发现了一个问题,其实也是早 ...
- C++读取一串不知个数的数字
#include <iostream> using namespace std; int main(){ ]; ; while(cin>>shuzu[i]){ i++; } ; ...
- JMS-activeMQ
参考资料: http://yuxisanren.iteye.com/blog/1912587 .JMS简介:JMS即Java Message Service,是Java 程序创建.发送.接收和读取企业 ...