二分枚举租用飞机的最大花费,然后用小于等于最大花费的边构建层次图(依据时间)

构图思路:   利用二元组(x,y)表示 x天y城市

  1. e天有飞机从a城市飞到b城市,能够承载x人,则添加单向边 ( e, a ) -> ( e+1, b ) 容量为x

  2. 每一天的a城市到第二天的a城市连边,容量为正无穷大

  3. 每一天的N城市到汇点T连边,容量为正无穷大

  4. 源点V与第0天的所有顶点连边,容量为当前城市0天初始人数

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
using namespace std;
const int M = ;
const int inf = 0x3f3f3f3f;
int n, d, m, tot;
struct Fight{
int u, v;
int c, p, e;
void input(){
scanf("%d%d%d%d%d",&u,&v,&c,&p,&e);
}
}fight[M];
int people[];
int S, T, N;
struct Edge{
int v, f, nxt;
}edge[];
int head[], idx; void AddEdge(int u,int v,int f){
edge[idx].v = v, edge[idx].f = f;
edge[idx].nxt = head[u], head[u] = idx++;
edge[idx].v = u, edge[idx].f = ;
edge[idx].nxt = head[v], head[v] = idx++;
}
void CreateGraph(int Max){
//init
idx = ;
memset( head, -, sizeof(head));
S = , T = (d+)*n+, N = (d+)*n+;
int u, v, c, p, e;
for(int i = ; i < m; i++){
u = fight[i].u, v = fight[i].v, c = fight[i].c, p = fight[i].p, e = fight[i].e;
if( p <= Max ) AddEdge( e*n+u, (e+)*n+v, c );
}
for(int i = ; i <= n; i++ )
AddEdge( S, i, people[i] );
for(int d1 = ; d1 < d; d1++ ){
for(int i = ; i <= n; i++ )
AddEdge( d1*n+i, (d1+)*n+i, inf );
}
for(int d1 = ; d1 <= d; d1++ )
AddEdge( d1*n+n, T, inf );
}
int h[], vh[]; int dfs(int u, int flow ){
if( u == T ) return flow;
int t = h[u]+, sum = flow;
for(int i = head[u]; ~i; i = edge[i].nxt ){
int v = edge[i].v;
if( edge[i].f && (h[v]+==h[u]) ){
int tmp = dfs( v, min(sum,edge[i].f) );
edge[i].f -= tmp, edge[i^].f += tmp; sum -= tmp;
if( sum == || h[S] == N ) return flow-sum;
}
}
for(int i = head[u]; ~i; i = edge[i].nxt )
if( edge[i].f ) t = min( t, h[ edge[i].v ] );
if( --vh[ h[u] ] == ) h[S] = N;
else ++vh[ h[u] = t+ ];
return flow - sum;
}
int sap(){
int maxflow = ;
memset( h, , sizeof(h));
memset( vh, , sizeof(vh));
vh[] = N;
while( h[S] < N ) maxflow += dfs( S, inf );
return maxflow;
}
int solve(){
int ans = -;
int l = , r = ;
while( l <= r ){
int mid = (l+r)>>;
CreateGraph( mid );
int tmp = sap(); //printf("tmp = %d\n", tmp);
if( tmp >= tot ) ans = mid, r = mid-;
else l = mid+;
}
return ans;
}
int main(){
int _;
scanf("%d",&_);
for(int Case = ; Case <= _; Case++){
scanf("%d%d%d",&n,&d,&m);
int u, v, c, p, e;
for(int i = ; i < m; i++)
fight[i].input();
tot = ;
for(int i = ; i <= n; i++){
scanf("%d", &people[i] );
tot += people[i];
}
int ans = solve();
printf("Case #%d: ", Case );
if( ans == - ) puts("Impossible");
else printf("%d\n", ans );
}
return ;
}

uva 10983 Buy one, get the rest free 二分判定层次图的更多相关文章

  1. UVa 1151 - Buy or Build(最小生成树)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. UVA 1151 Buy or Build MST(最小生成树)

    题意: 在平面上有n个点,要让所有n个点都连通,所以你要构造一些边来连通他们,连通的费用等于两个端点的欧几里得距离的平方.另外还有q个套餐,可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相 ...

  3. UVA 1151 Buy or Build (最小生成树)

    先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点.正确性是基于一个贪心, 在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少. ...

  4. UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)

    题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...

  5. uva 1151 - Buy or Build poj 2784 Buy or Build(最小生成树)

    最小生成树算法简单 只是增加了一些新的东西,对于需要最小生成树算法 和中 并检查使用的一系列 还有一些更深入的了解. 方法的一些复杂问题 #include<cstdio> #include ...

  6. UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)

    题意:给定n个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...

  7. UVa 1151 Buy or Build【最小生成树】

    题意:给出n个点的坐标,现在需要让这n个点连通,可以直接在点与点之间连边,花费为两点之间欧几里得距离的平方,也可以选购套餐,套餐中所含的点是相互连通的 问最少的花费 首先想kruskal算法中,被加入 ...

  8. UVA - 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)

    题意:平面上有n个点(1<=n<=1000),你的任务是让所有n个点连通.可以新建边,费用等于两端点欧几里德距离的平方.也可以购买套餐(套餐中的点全部连通).问最小费用. 分析: 1.先将 ...

  9. POJ2828 Buy Tickets [树状数组,二分答案]

    题目传送门 Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 22611   Accepted: 110 ...

随机推荐

  1. mysql中查看数据库的版本,什么版本

    需求:查看当前使用的数据库是哪个版本的,什么版本 select version(); 查询结果: 备注:通过version()函数查询出来当前使用的数据库版本是5.5.57-log 文档创建时间:20 ...

  2. HTML标签嵌套规则

    摘要:  最近在整理项目时发现有些同事写的页面代码嵌套的太多,而且有些嵌套不对,比如<a><div>内容</div></a>.虽然功能实现了,但是对于浏 ...

  3. linux 实时查看Tomcat日志信息

    cd /../tomcat/logs 进入tomcat/logs/文件夹下  # tail -f catalina.out

  4. 让Json更懂中文(JSON_UNESCAPED_UNICODE)

    我们知道, 用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式, 还会在一定程度上增加传输的数据量. <?php echo json_ ...

  5. [Arch] 04. Software Architectural Patterns

    让我们一起 回忆: 原则 基本认识 S 应该仅有一个引起它变化的原因 O 在不被修改的前提下被扩展 L 尽量从抽象类继承 I 应该依赖于抽象 D 倾向瘦接口 让我们开始 新课: [Design Pat ...

  6. ios7注意事项随笔

    1,修改状态栏的样式和隐藏. 首先,需要在Info.plist配置文件中,增加键:UIViewControllerBasedStatusBarAppearance,并设置为YES: 然后,在UIVie ...

  7. RedHat6.5-Linux安装telnet服务

    1 下载以下三个包 telnet-0.17-47.el6.x86_64.rpm(telnet客户端) telnet-server-0.17-47.el6.x86_64.rpm(telnet服务端) x ...

  8. flexbox父盒子flex-direction属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Python 管理 MySQL

    Python MySQLdb 模块 Python pymysql 模块 Python SQLAlchemy 模块 Python ConfigParser 模块 Python 创建 MySQL 配置文件 ...

  10. Popupwindow全屏问题

    //sdk > 21 解决 标题栏没有办法遮罩的问题 popupWindow.setClippingEnabled(false);