pku 2455 Secret Milking Machine

二分答案 有点类似与 2112

 

 
  
#include < iostream >
using namespace std;
#define MAXN 205
#define INF 2110000000
#define MIN(x,y) (x<y?x:y)
int map[MAXN][MAXN];
int mat[MAXN][MAXN];
int n,p,t;
typedef
struct node
{
int x,y,len;
}Q;
Q q[
40001 ];
void inti( int mindis)
{
int i;
memset(mat,
0 , sizeof (mat));
for (i = 1 ;i <= p;i ++ )
{
if (mindis >= q[i].len)
{
mat[q[i].x][q[i].y]
+= 1 ;
mat[q[i].y][q[i].x]
+= 1 ;
}
}
}
int max_flow( int num, int map[][MAXN], int source, int sink) // 参数含义:结点数量 网络 源点 汇点
{
int my_queue[MAXN],queue_first,queue_end; // 数组做队列 实现BFS搜索路径
int pre[MAXN],min_flow[MAXN]; // 记录结点的父节点 当前路径中最小的一段的值,也即限制值
int flow[MAXN][MAXN]; // 记录当前网络中的流
int ans = 0 ; // 最终结果
memset(flow, 0 , sizeof (flow));
while ( 1 ) // 一直循环,直到不存在增广路径
{
queue_first
= 0 ; // 初始化队列
queue_end = 0 ;
my_queue[queue_end
++ ] = source;
memset(pre,
- 1 , sizeof (pre));
min_flow[source]
= INF;
pre[source]
=- 2 ; // 源点的父节点需特殊标示
while (queue_first < queue_end) // BFS寻找增广路径
{
int temp = my_queue[queue_first ++ ]; // 出队列
for ( int i = 1 ;i < num;i ++ ) // 由结点temp往外扩展
{
if (pre[i] ==- 1 && flow[temp][i] < map[temp][i]) // 当结点i还未被探索到,并且还有可用流量
{
my_queue[queue_end
++ ] = i; // 加入队列
pre[i] = temp; // 标示父节点
min_flow[i] = MIN(min_flow[temp],(map[temp][i] - flow[temp][i])); // 求得min_flow
}
}
if (pre[sink] !=- 1 ) // sink的父节点不为初始值,说明BFS已经找到了一条路径
{
int k = sink;
while (pre[k] >= 0 )
{
flow[pre[k]][k]
+= min_flow[sink]; // 将新的流量加入flow
flow[k][pre[k]] =- flow[pre[k]][k];
k
= pre[k];
}
break ;
}
}
if (pre[sink] ==- 1 ) return ans; // 不存在增广路径,返回
else ans += min_flow[sink];
}
return ans;
}
int main()
{
int i,j,k;
int right,left;
while (scanf( " %d%d%d " , & n, & p, & t) != EOF)
{
left
= 99999999 ;
right
=- 99999999 ;
for (i = 1 ;i <= p;i ++ )
{
scanf(
" %d%d%d " , & q[i].x, & q[i].y, & q[i].len);
if (q[i].len < left) left = q[i].len;
if (q[i].len > right) right = q[i].len;
}
while (left <= right)
{
int mid = (left + right) / 2 ;
inti(mid);
int temp = max_flow(n + 1 ,mat, 1 ,n);
if (temp >= t) right = mid - 1 ;
else left = mid + 1 ;
}
printf(
" %d\n " ,left);
}
return 0 ;
}

 

 

 

转载于:https://www.cnblogs.com/ACAC/archive/2010/05/19/1739668.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值