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

分析:可以用费用流求解,因为要求长度和最大,视作从源点出发的流量为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. hdu 2059:龟兔赛跑(动态规划 DP)

    龟兔赛跑 Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submissi ...

  2. 40 个顶级 jQuery 图片、内容滑块和幻灯片

    在这个快速发展的网络世界中,我们使用图片.内容滑块和幻灯片来给网站实现良好.有吸引力的外观.你可以吸引浏览者借助图像滑块让网站更加具有活力.使用 JavaScript 可以轻松实现轻量级的图片和内容滑 ...

  3. HDU4417 (Super Mario)

    题目链接:传送门 题目大意:一个大小为 n 的数组,m组询问,每组询问[x,y]内<=v的数的数量. 题目思路:主席树(注意询问时数组下标越界问题) #include <iostream& ...

  4. 1358 棋盘游戏[状压dp]

    1358 棋盘游戏  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 这个游戏在一个有10*10 ...

  5. 170410、java Socket通信的简单例子(TCP)

    服务端代码: package com.bobohe.socket; import java.io.*; import java.net.*; import java.applet.Applet; pu ...

  6. POJ 2374 Fence Obstacle Course(线段树+动态规划)

    Fence Obstacle Course Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 2524   Accepted:  ...

  7. Ubuntu 16.04修改配置静态IP和DNS

    Ubuntu 16.04修改配置静态IP和DNS 1.修改interfaces 文件 sudo gedit /etc/network/interfaces 2.添加 例如: auto enp0s25 ...

  8. java 常用资源

    java高手真经:http://pan.baidu.com/share/link?uk=2100475681&shareid=2381645927#path=%252F%255Bwww.jav ...

  9. HOW TO FIX "EXPECTED BEGIN_ARRAY BUT WAS BEGIN_OBJECT" IN RETROFIT ?

    https://www.freshbytelabs.com/2018/05/how-to-fix-expected-beginarray-but-was.html HOW TO FIX "E ...

  10. C++之贪吃蛇

    #include<iostream> #include<cstdio> #include<cstdlib> #include<ctime> #inclu ...