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 仅包含一个整数,表示可以 ...
随机推荐
- 九度OJ 1437 To Fill or Not to Fill
题目大意:小明从杭州去往某目的地,要经过一些加油站,每个加油站的价格不一样.若能顺利到达,求加油费用最少为多少,否则求出能行驶的最远距离. 思路:贪心算法 1>若下一加油站的价格更便宜,则只需走 ...
- phpcms:五、网站首页(index.html)
1.经典案例:图文列表:{pc:content action="position" posid="2" order="listorder DESC& ...
- CPU使用率统计办法
我们在搞性能测试的时候,对后台服务器的CPU利用率监控是一个常用的手段.服务器的CPU利用率高,则表明服务器很繁忙.如果前台响应时间越来越大,而后台CPU利用率始终上不去,说明在某个地方有瓶颈了,系统 ...
- event.keyCode列表
Keycode对照表 字母和数字键的键码值(keyCode) 按键 键码 按键 键码 按键 键码 按键 键码 A 65 J 74 S 83 1 49 B 66 K 75 T 84 2 50 C 67 ...
- AJAX上传文件
function up_files() { var fileSelect = document.getElementById('file-select'); var files = fileSelec ...
- [AngularJS] Angular 1.5 multiple transclude
If you know ui-router, multi-transclude should be easy for you also. In previou Angular version < ...
- 【剑指offer】左旋转字符串
转载请注明出处:http://blog.csdn.net/ns_code/article/details/27366485 题目描写叙述: 汇编语言中有一种移位指令叫做循环左移(ROL),如今有个简单 ...
- samba错误
1.session setup failed: NT_STATUS_LOGON_FAILURE 该错误表示用户有误, 可能是用户不存在, 也有可能是密码错误, 或者用户只是在samba和系统的用户中的 ...
- 你所不知道的java编程思想
读thinking in java这本书的时候,有这么一句话“在编译单元的内部,可以有一个公共(public)类,它必须拥有与文件相同的名字” 有以下疑问: 在一个类中说可以有一个public类,那是 ...
- Impala 源码分析-FE
By yhluo 2015年7月29日 Impala 3 Comments Impala 源代码目录结构 SQL 解析 Impala 的 SQL 解析与执行计划生成部分是由 impala-fronte ...