Dsc是个送货员,他所在的地方有n个城市,k条道路,在moxin下了电脑订单后,dsc需要从他老板所在的工厂(序号为1)运送电脑到达moxin的网吧(序号为n),dsc比较懒,所以他一天只运一次货,且从工厂到moxin网吧的时间需控制在t秒内,已知每台电脑重m 千克,途中经过许多个城市,城市之间可能会有道路,每条道路限重Mi kg(当载重量>限重则不允许通过),经过每条路需Ti秒时间(道路必然是双向路),dsc想知道他一天最多能运多少台电脑到moxin的网吧?
Dsc老板的工厂在城市1,moxin的网吧在城市n
Input
第一行有四个整数n, k, m, t分别代表n个城市,k条道路,每台电脑重m千克,时间限制为t秒
第二行开始有k行,每行有四个整数a,b,Mi,Ti分别代表a城市到b城市有一条路限重Mi千克,通过需要Ti秒时间
保证图连通且无重边
1<=n<=1e4
n<=k<=5e4
1<=m<=100
1<=t<=1e8
1<=a,b<=n
1<=Mi<=1e5
1<=Ti<=t
Output
一个整数,表示dsc一天最多能运多少台电脑到moxin网吧
SampleInput
6 6 6 6
1 4 66 2
4 5 55 2
5 6 44 2
1 2 33 1
2 3 22 1
3 6 11 1
SampleOutput
7
题意:每条边上有承重和时间 在满足时间T下 最多能运多少台电脑 每台电脑重量为m n个点 k条路
思路:直接二分能运多少台电脑 那么总重量就是 m 乘上电脑个数 然后根据这个条件 每条路上的承重必须大等于这个值 然后跑dijkstra 判断是否满足在时间内到达 满足则将台数上调 否则下调 得出答案
数据范围大 记得开long long
#include <bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define LL long long
const int N = 1e4 + 5,M = 5e4 + 5;
int n;
LL t;
struct Edge
{
int to;
int next;
LL w,t;
} edge[M << 1];
int cnt,head [N];
void add(int u,int v,LL w,LL t)
{
edge[cnt].w = w;
edge[cnt].t = t;
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt ++ ;
}
struct node
{
int to;
LL w;///时间
node() {}
node(int tt,LL ww):to(tt),w(ww) {};
friend bool operator < (const node &a,const node &b)
{
return a.w > b.w;
}
};
LL dist[N];
bool vis[N];
void init()
{
for(int i = 0; i <= n; i ++)
{
head[i] = -1;
vis[i] = 0;
dist[i] = INF;
}
cnt = 0;
}
bool dijkstra(LL val)
{
for(int i = 0; i <= n; i ++)
{
vis[i] = 0;
dist[i] = INF;
}
priority_queue <node> que;
que.push(node(1,0));
while(!que.empty())
{
node now = que.top();
que.pop();
if(vis[now.to])
continue;
vis[now.to] = 1;
dist[now.to] = now.w;
for(int i = head[now.to]; ~i ; i = edge[i].next)
{
node next = now ;
next.to = edge[i].to ;
if(!vis[next.to] && edge[i].w >= val)///边的承重够大
{
next.w += edge[i].t;///加上时间
que.push(next);
}
}
}
if(dist[n] <= t)
return 1;
return 0;
}
int main()
{
int k ;
LL m ;
scanf("%d%d%lld%lld",&n,&k,&m,&t);
init();
LL l = 0;
LL r = 0;
for(int i = 0; i < k; i ++)
{
int x,y;
LL v, time;
scanf("%d%d%lld%lld",&x,&y,&v,&time);
r = max(r,v / m + 1);
add(x,y,v,time);
add(y,x,v,time);
}
while(l + 1 < r)
{
LL mid = l + r >> 1;
if(dijkstra(mid * m))///mid*m为总重量
l = mid;
else
r = mid;
}
printf("%lld\n",l);
return 0;
}