Gym - 100814G It is all about wisdom
有N个城市,M条边,每条边有一个C值,表示花费,有一个智慧值W,智力值必须超过该边的w,才能通过该条边。输入数据给了一个总的花费K,求从1到n,智力值最少要达到多少,且花费必须小于K。
题解:先找一次最短路,判断最小花费是否小于k,再对w值二分查找,一直找到最小的满足条件的路径。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <bitset>
#define INF 0x3f3f3f3f
#define eps 1e-6
#define PI 3.1415926
#define mod 1000000009
#define base 2333
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10;
const int maxx = 1e3 + 10;
inline void splay(int &v) {
v=0;char c=0;int p=1;
while(c<'0' || c >'9'){if(c=='-')p=-1;c=getchar();}
while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
v*=p;
}
inline void splay(LL &v) {
v=0;char c=0;int p=1;
while(c<'0' || c >'9'){if(c=='-')p=-1;c=getchar();}
while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
v*=p;
}
int t, n, m, u, v, len, head[maxn], vis[maxn];
LL k, mx, c, w, dis[maxn];
struct node {
int to, next;
LL val, w;
} e[maxn<<1];
void add(int from, int to, LL val, LL w) {
e[len].to = to;
e[len].val = val;
e[len].w = w;
e[len].next = head[from];
head[from] = len++;
}
bool SPFA(LL val) {
for(int i = 0; i < maxn; i++) {
vis[i] = 0;
dis[i] = 1e18;
}
queue<int> q;
q.push(1);
vis[1] = 1, dis[1] = 0;
while(!q.empty()) {
int cur = q.front(); q.pop();
vis[cur] = 0;
for(int i = head[cur]; i != -1; i = e[i].next) {
int id = e[i].to;
if(val < e[i].w || dis[cur]+e[i].val > k) continue;
if(dis[id] > dis[cur]+e[i].val) {
dis[id] = dis[cur]+e[i].val;
if(!vis[id]) {
vis[id] = 1;
q.push(id);
}
}
}
}
return dis[n] < k;
}
void solve() {
splay(t);
while(t--) {
splay(n), splay(m), splay(k);
memset(head, -1, sizeof(head));
len = 0, mx = 0;
for(int i = 0; i < m; i++) {
splay(u), splay(v), splay(c), splay(w);
mx = max(mx, w);
add(u, v, c, w);
add(v, u, c, w);
}
if(!SPFA(mx)) {
printf("-1\n");
continue ;
}
LL l = 1, r = mx, mid;
while(l < r) {
mid = (l+r)>>1;
if(SPFA(mid)) r = mid;
else l = mid+1;
}
printf("%lld\n", l);
}
}
int main() {
//srand(time(NULL));
//freopen("kingdom.in","r",stdin);
//freopen("kingdom.out","w",stdout);
solve();
}