标签:
【HDU 1839】 Delay Constrained Maximum Capacity Path(二分+最短路)
2 2 1 10 1 2 13 10 4 4 20 1 2 1000 15 2 4 999 6 1 3 100 15 3 4 99 4
13 99
路线的流量是指路线中能承受的最大流量 即路线中一条流量最小的路径的流量
给的边50000条 当时没想出来怎么做 只知道时间很长 感觉可以搜 但不知道怎么搜 像是最小费的变形(费用不超过时的单条最大流)
之后知道是二分+最短路 因为边少 单独存一下排个序 然后二分 没二分到一个流量 看一下1->n存不存在流量>=该流量且在时间范围内的路径 然后不断二分+搜
二分要满足单调 排序后流量单调了 然后流量越大 可行路线越少 流量越少可行路就越多 因此是单减的 满足二分条件
代码如下:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
struct Edge
{
int v,c,w,next;
};
//邻接表存图
int head[10100];
Edge eg[100100];
int tp,n,T;
//边流量 排序后用来二分
int cost[100100];
//SPFA
int dis[10100];
bool vis[10100];
void Add(int u,int v,int c,int w)
{
eg[tp].v = v;
eg[tp].next = head[u];
eg[tp].c = c;
eg[tp].w = w;
head[u] = tp++;
}
void init()
{
memset(head,-1,sizeof(head));
tp = 0;
}
//SPFA 检查是否可行
bool can(int c)
{
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
queue <int> q;
dis[1] = 0;
q.push(1);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for(int i = head[u]; i != -1; i = eg[i].next)
{
int v = eg[i].v;
int cs = eg[i].c;
int w = eg[i].w;
if(cs >= c && dis[v] > dis[u]+w)
{
dis[v] = dis[u]+w;
if(!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
//流量满足的情况下 最小花费是否满足限制
return dis[n] <= T;
}
int main()
{
int t,m,l,r,ans;
int u,v,c,w;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d %d %d",&n,&m,&T);
for(int i = 0; i < m; ++i)
{
scanf("%d %d %d %d",&u,&v,&c,&w);
Add(u,v,c,w);
Add(v,u,c,w);
cost[i] = c;
}
//排序二分
sort(cost,cost+m);
l = 0, r = m-1, ans = -1;
while(l <= r)
{
m = (l+r)>>1;
//该流量下可行
if(can(cost[m]))
{
ans = m;
l = m+1;
}else r = m-1;
}
printf("%d\n",cost[ans]);
}
return 0;
}
【HDU 1839】 Delay Constrained Maximum Capacity Path(二分+最短路)
标签:
原文地址:http://blog.csdn.net/challengerrumble/article/details/50094569