Gym

来源:互联网 发布:html5个人网站源码 编辑:程序博客网 时间:2024/05/16 19:18

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 2333using 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();}


原创粉丝点击