POJ3228二分最大流
题意:
有n个点,每个点有两个权值,金子数量还有仓库容量,金子可以存在自己的仓库里或者是别的仓库里,仓库和仓库之间有距离,问所有金子都必须存到库里最大距离的最小是多少?
思路:
比较简单,方法也不唯一,大体可以这样,先二分,然后用最大流或者匹配..来判断是不是满足就行了,我用的是二分最大流,具体代码在下面。
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N_node 400 + 50
#define N_edge 200 * 200 * 2 + 10000
#define INF 1000000000
using namespace std;
typedef struct
{
int to ,cost ,next;
}STAR;
typedef struct
{
int a ,b ,c;
}EDGE;
typedef struct
{
int x ,t;
}DEP;
STAR E[N_edge];
EDGE edge[N_edge];
DEP xin ,tou;
int list[N_node] ,listt[N_node] ,tot;
int deep[N_node];
int c1[N_node] ,c2[N_node];
int num[N_edge] ,numt[N_edge];
void add(int a ,int b ,int c)
{
E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot;
E[++tot].to = a;
E[tot].cost = c;
E[tot].next = list[b];
list[b] = tot;
}
bool BFS_DEEP(int s ,int t ,int n)
{
memset(deep ,255 ,sizeof(deep));
xin.x = s ,xin.t = 0;
queue<DEP>q;
q.push(xin);
deep[s] = 0;
while(!q.empty())
{
tou = q.front();
q.pop();
for(int k = list[tou.x] ;k ;k = E[k].next)
{
xin.x = E[k].to;
xin.t = tou.t + 1;
if(deep[xin.x] != -1 || !E[k].cost)
continue;
deep[xin.x] = xin.t;
q.push(xin);
}
}
for(int i = 0 ;i <= n ;i ++)
listt[i] = list[i];
return deep[t] != -1;
}
int minn(int x ,int y)
{
return x < y ? x : y;
}
int DFS_Flow(int s, int t ,int flow)
{
if(s == t) return flow;
int nowflow = 0;
for(int k = listt[s] ;k ;k = E[k].next)
{
listt[s] = k;
int c = E[k].cost ,to = E[k].to;
if(!c || deep[to] != deep[s] + 1)
continue;
int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));
nowflow += tmp;
E[k].cost -= tmp;
E[k^1].cost += tmp;
if(nowflow == flow) break;
}
if(!nowflow) deep[s] = 0;
return nowflow;
}
int DINIC(int s ,int t ,int n)
{
int ans = 0;
while(BFS_DEEP(s ,t ,n))
{
ans += DFS_Flow(s ,t ,INF);
}
return ans;
}
int GetMaxFlow(int mid ,int n ,int m)
{
memset(list ,0 ,sizeof(list));
tot = 1;
for(int i = 1 ;i <= n ;i ++)
{
add(0 ,i ,c1[i]);
add(i ,i + n ,INF);
add(i + n ,n + n + 1 ,c2[i]);
}
for(int i = 1 ;i <= m ;i ++)
{
if(edge[i].c <= mid)
{
add(edge[i].a ,edge[i].b + n ,INF);
add(edge[i].b ,edge[i].a + n ,INF);
}
}
return DINIC(0 ,n + n + 1 ,n + n + 1);
}
int main ()
{
int n ,m ,i ,s1 ,s2;
while(~scanf("%d" ,&n) && n)
{
s1 = s2 = 0;
for(i = 1 ;i <= n ;i ++)
{
scanf("%d" ,&c1[i]);
s1 += c1[i];
}
for(i = 1 ;i <= n ;i ++)
{
scanf("%d" ,&c2[i]);
s2 += c2[i];
}
scanf("%d" ,&m);
for(i = 1 ;i <= m ;i ++)
{
scanf("%d %d %d" ,&edge[i].a ,&edge[i].b ,&edge[i].c);
numt[i] = edge[i].c;
}
if(s2 < s1)
{
printf("No Solution\n");
continue;
}
sort(numt + 1 ,numt + m + 1);
int numid = 0;
for(i = 1 ;i <= m ;i ++)
if(i == 1 || numt[i] != numt[i-1])
num[++numid] = numt[i];
num[0] = 0;
int low = 0 ,up = numid ,mid ,ans = -1;
while(low <= up)
{
mid = (low + up) >> 1;
if(GetMaxFlow(num[mid] ,n ,m) == s1)
{
ans = num[mid];
up = mid - 1;
}
else low = mid + 1;
}
if(ans == -1) printf("No Solution\n");
else printf("%d\n" ,ans);
}
return 0;
}
POJ3228二分最大流的更多相关文章
- uvalive 3231 Fair Share 公平分配问题 二分+最大流 右边最多流量的结点流量尽量少。
/** 题目: uvalive 3231 Fair Share 公平分配问题 链接:https://vjudge.net/problem/UVALive-3231 题意:有m个任务,n个处理器,每个任 ...
- poj 2391 Ombrophobic Bovines 最短路 二分 最大流 拆点
题目链接 题意 有\(n\)个牛棚,每个牛棚初始有\(a_i\)头牛,最后能容纳\(b_i\)头牛.有\(m\)条道路,边权为走这段路所需花费的时间.问最少需要多少时间能让所有的牛都有牛棚可待? 思路 ...
- HDU3081 Marriage Match II —— 传递闭包 + 二分图最大匹配 or 传递闭包 + 二分 + 最大流
题目链接:https://vjudge.net/problem/HDU-3081 Marriage Match II Time Limit: 2000/1000 MS (Java/Others) ...
- HDU-3081-Marriage Match II 二分图匹配+并查集 OR 二分+最大流
二分+最大流: 1 //题目大意:有编号为1~n的女生和1~n的男生配对 2 // 3 //首先输入m组,a,b表示编号为a的女生没有和编号为b的男生吵过架 4 // 5 //然后输入f组,c,d表示 ...
- hdu4560 不错的建图,二分最大流
题意: 我是歌手 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Subm ...
- POJ3228 并查集或二分最大流枚举答案
忘记写题意了.这题题意:给出每个地点的金矿与金库的数量,再给出边的长度.求取最大可通过边长的最小权值使每个金矿都能运输到金库里. 这题和之前做的两道二分枚举最大流答案的问法很相识,但是这里用最大流速度 ...
- BZOJ 1305: [CQOI2009]dance跳舞 二分+最大流
1305: [CQOI2009]dance跳舞 Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲 ...
- loj 1167(二分+最大流)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26881 思路:我们可以二分最大危险度,然后建图,由于每个休息点只能 ...
- BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图
这道逼题!感受到了数学对我的深深恶意(#‵′).... 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB S ...
随机推荐
- postman接口测试之设置全局变量和设置环境变量和全局变量
一.概念 1.环境变量 就是接口的域名或IP地址. 2.全局变量 就是一个作用域为整个postman的变量. 二.使用场景 1.环境变量 在测试的过程中,经常会频繁切换环境,本地环境验证.发布到测试环 ...
- Asp.Net Core WebAPI中启用XML格式数据支持
因为XML是一种非常常用的数据格式,所以Asp.Net core提供了非常便利的方式来添加对XML格式的支持 只需要在IOC注册Controller服务的后面跟上.AddXmlDataContract ...
- Chrome OS超便捷安装指南
Chrome OS是一款Google开发的基于PC的操作系统. Google Chrome OS是一款基于Linux的开源操作系统.Google在自己的官方博客表示,初期,这一操作系统将定位于上网本. ...
- java线程实现的三种方式以及静态代理
线程 一个进程中若开辟多个线程,线程的运行由调度器控制,先后顺序不能人为干预. 实现方式 继承 Thread类 调用run方法,只有主线程一条路 调用start方法,主线程和子线程并行交替执行 pub ...
- Codeforces Round #574 (Div. 2) E. OpenStreetMap 【单调队列】
一.题目 OpenStreetMap 二.分析 对于二维空间找区间最小值,那么一维的很多好用的都无法用了,这里可以用单调队列进行查找. 先固定一个坐标,然后进行一维的单调队列操作,维护一个区间长度为$ ...
- 在Python中创建M x N的数组
在Python中创建M x N的数组 一般有三种方法: 列表乘法 dp = [[0] * n] * m for 循环 dp= [[0 for _ in range(n)] for _ in range ...
- Reverse 高校网络信息安全运维挑战赛
Reverse 高校网络信息安全运维挑战赛 1 signed int sub_403CC0() 2 { 3 unsigned int v0; // eax 4 int key_lens; // eax ...
- 别再面向 for 循环编程了,JDK 自带的观察者模式就很香!
大家好,你还在面向 for 循环编程吗? 还有谁不会用观察者模式吗? 本篇栈长带来<观察者模式>理论及实战- 什么是观察者模式? 观察者模式(Observer Pattern)定义了对象间 ...
- SqlServer视图的创建与使用
SqlServer系列之视图的创建与使用: 什么是视图? 视图的概述 在数据查询中,可以看到数据表设计过程中,考虑到数据的冗余度低.数据一致性等问题,通常对数据表的设计要满足范式的要求,因此也会造成一 ...
- 翻译:《实用的Python编程》07_04_Function_decorators
目录 | 上一节 (7.3 返回函数) | 下一节 (7.5 装饰方法) 7.4 函数装饰器 本节介绍装饰器(decorator).因为这是一个高级主题,所以我们只做简单介绍. 译注:根据译者个人的猜 ...