题意:对于给定的物品,求两个在高度上单调不递增,权值上单调不递减的序列,使二者长度之和最大。

分析:可以用费用流求解,因为要求长度和最大,视作从源点出发的流量为2的费用流,建负权边,每个物品只能取一次,且花费为-1。将每个物品拆成入点和出点,中间建容量为1,费用为-1的弧。建源点s和超级源点S,S到s建容量为2,费用为0的弧,表示只有两个序列。源点s向每个入点建容量为1,费用为0的弧,表示每个点都可作为序列的首项。出点向汇点建容量为1,费用为0的弧,表示每个点都可作为序列的末项。

对给定物品按高度和权值排序后,从权值较小的物品向权值较大的物品建边,容量为1,花费为0。

跑出费用流后对花费取反就是答案。spfa要用栈优化,队列会T。

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
const int MAXN = 2005;
const int MAXM = 2000005;
const int INF = 0x3f3f3f3f;
struct Edge{
int to, next, cap, flow, cost;
} edge[MAXM];
int head[MAXN], tot;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N;
void init(int n)
{
N = n;
tot = 0;
memset(head, -1, sizeof(head));
} void AddEdge(int u, int v, int cap, int cost)
{
edge[tot] = (Edge){v,head[u],cap,0,cost};
head[u] = tot++;
edge[tot] = (Edge){u,head[v],0,0,-cost};
head[v] = tot++;
} bool spfa(int s, int t){
stack<int> q;
for (int i = 0; i < N; i++){
dis[i] = INF;
vis[i] = false;
pre[i] = -1;
}
dis[s] = 0;
vis[s] = true;
q.push(s);
while (!q.empty()){
int u = q.top();
q.pop();
vis[u] = false;
for (int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].to; if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost){
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
if (pre[t] == -1) return false;
else return true;
} int minCostMaxflow(int s, int t, int &cost){
int flow = 0;
cost = 0;
while (spfa(s, t)){
int Min = INF;
for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){
if (Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
}
for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){
edge[i].flow += Min;
edge[i ^ 1].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
} struct Node{
int h,w;
bool operator<(const Node &rhs) const{
if(h==rhs.h) return w<rhs.w;
return h>rhs.h;
}
}vz[MAXN]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T; scanf("%d",&T);
while(T--){
int N; scanf("%d",&N);
int u,v;
for(int i=1;i<=N;++i){
scanf("%d %d",&vz[i].h,&vz[i].w);
}
sort(vz+1,vz+N+1);
init(2*N+4);
int s = 2*N+1, t = 2*N+2;
int S = 0;
for(int i=1;i<=N;++i){
AddEdge(i+N,t,1,0);
AddEdge(s,i,1,0);
AddEdge(i,i+N,1,-1);
int x = INF;
for(int j=i+1;j<=N;++j){
if(vz[i].w<=vz[j].w){
AddEdge(i+N,j,1,0);
}
}
}
AddEdge(S,s,2,0);
int cost;
minCostMaxflow(S,t,cost);
printf("%d\n",-cost);
}
return 0;
}

HDU - 5406 CRB and Apple (费用流)的更多相关文章

  1. 2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple

    CRB and Apple Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  2. HDU 5644 King's Pilots 费用流

    King's Pilots 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5644 Description The military parade w ...

  3. HDU 3667 Transportation(网络流之费用流)

    题目地址:HDU 3667 这题的建图真是巧妙...为了保证流量正好达到k.须要让每一次增广到的流量都是1,这就须要把每一条边的流量都是1才行.可是每条边的流量并非1,该怎么办呢.这个时候能够拆边,反 ...

  4. 【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004

    题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. ...

  5. HDU 3488--Tour(KM or 费用流)

    因为每个点只能经过一次 所以考虑拆点 这题有坑,有重边.. KM算法 把一个点拆成入点和出点 入点在X部,出点在Y步. 如果u,v之间有路径,就在X部的u点连接Y部的v点 求完美匹配. 当完美匹配的时 ...

  6. hdu 1853 Cyclic Tour 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 There are N cities in our country, and M one-way ...

  7. Going Home HDU - 1533 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 给一个网格图,每两个点之间的匹配花费为其曼哈顿距离,问给每个的"$m$"匹配到一个&q ...

  8. Tour HDU - 3488 有向环最小权值覆盖 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=3488 给一个无源汇的,带有边权的有向图 让你找出一个最小的哈密顿回路 可以用KM算法写,但是费用流也行 思路 1 ...

  9. HDU 5988 Coding Contest(费用流+浮点数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 题目大意: 给定n个点,m条有向边,每个点是一个吃饭的地方,每个人一盒饭.每个点有S个人,有B盒 ...

随机推荐

  1. Mysql命令行添加用户并且给予远程访问服务器的权限

    --查询用户SELECT User, Password, Host FROM user; --创建一个用户,任意主机可以登录%,密码是123456 '; -- 给用户赋予所有权限 GRANT ALL ...

  2. Huber-Markov先验模型相关

    随机概率重建-MAP算法 随机概率重建:利用贝叶斯理论作为框架,理想图像的先验知识作为约束条件进行图像重建.常用的随机概率超分辨率重建包括最大后验概率估计法(MAP)和极大似然估计法(ML). MAP ...

  3. python 发送email

    pyton smtplib发送邮件 在邮件中设置并获取到 smtp域名 在脚本中执行命名,收件人可以是 多个,在列表中 import smtplib from email.mime.text impo ...

  4. linux命令之rpm

    1.查询一个包是否被安装的命令rpm -q  < rpm package name> 2.列出所有被安装的rpm package 命令rpm -qa

  5. Java Web项目--显示一个静态页面

    我们可以在Eclipse中新建一个Dynamic Web Project,然后在项目的WebContent目录下新建一个Html文件page1.html,其内容如下: <!DOCTYPE htm ...

  6. 获取jqGrid中选择的行的数据以及 jqGrid获得所有行数据的方法

    获取jqGrid中选择的行的数据: 获取选择一行的id,如果你选择多行,那下面的id是最后选择的行的id:   1 var id=$('#gridTable').jqGrid('getGridPara ...

  7. PHP获取当前日期和时间格式化方法

    使用函式 date() 实现 <?php echo $showtime=date("Y-m-d H:i:s");?> 显示的格式: 年-月-日 小时:分钟:妙 相关时间 ...

  8. Babel6.x的安装

    1.首先安装babel-cli(用于在终端使用babel) npm install -g babel-cli 2.然后安装babel-preset-es2015插件 npm install --sav ...

  9. 160418、ztree权限菜单

    1.页面中引用ztree的css和js(大家自行下载ztree) <link rel="stylesheet" href="${ctx}/resources/js/ ...

  10. vim简单的配置

    "设置当文件被改动时自动载入 set autoread "在左侧行号 set nu "tab长度为4 "覆盖文件时不备份 set nobackup " ...