zoukankan      html  css  js  c++  java
  • CSU-1989 赶路的小X

    题目链接

    http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=1989

    题目

    Description

    A国一共有N座城市,由M条双向公路连接。小X现在位于S市,他正在赶往T市。小X的时间有限,他还剩下L的时间。另外,到达每座城市,小X都需要缴纳一定的过路费,包括S市和T市。在缴纳过路费时,单次的花费越多,小X越不开心。他希望能够在规定时间内到达T市的同时,使缴纳过路费最多的那次最少。

    Input

    输入包含不超过10组数据。
    对于每组数据,第一行5个正整数,N,M,S,T,L(N≤10000;M≤50000;S≤N;T≤N;L≤1000000000),意义如上文所述。接下来的1行有N个正整数,第i个数表示经过城市i需要缴纳的过路费Fi(Fi≤1000000000)。接下来M行,每行3个正整数Ui,Vi,Wi,(Ui≤N;Vi≤N;Wi≤1000000000)描述一条公路,表示从城市Ui到城市Vi需要花费Wi的时间。

    Output

    对于每组数据,输出一行一个正整数,表示小X交费最多的那次的最小值。如果小X无论如何也无法在规定时间内到达城市T,输出-1。

    Sample Input

    4 4 1 4 10
    3 6 9 3
    1 3 1
    2 1 3
    3 4 5
    4 2 7
    4 4 1 4 4
    3 6 9 3
    1 3 1
    2 1 3
    3 4 5
    4 2 7
    5 5 1 4 6
    3 6 9 3 6
    1 3 1
    2 1 3
    3 4 5
    4 5 1
    5 2 2
    

    Sample Output

    6
    -1
    6
    

    题解

    过路费最多的那次最少,很容易想到二分答案,然后检查,检查就跑一边dijkstra,在跑的时候加入条件边权必须小于mid,最后判断一下d[t]是否大于L,大于的话就l = mid + 1,否则r = mid - 1,记录一下ans即可

    AC代码

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 100050
    #define pi pair<int, int>
    using namespace std;
    inline ll getnum() {
    	ll ans = 0; char c; ll flag = 1;
    	while (!isdigit(c = getchar()) && c != '-');
    	if (c == '-') flag = -1; else ans = c - '0';
    	while (isdigit(c = getchar())) ans = ans * 10 + c - '0';
    	return ans * flag;
    }
    struct node {
    	ll v, w;
    	node(ll vv, ll ww) {
    		v = vv;
    		w = ww;
    	}
    };
    vector<node> G[maxn];
    void adde(ll a, ll b, ll w) {
    	G[a].push_back(node(b, w));
    	G[b].push_back(node(a, w));
    }
    ll n, m, s, t, l;
    ll w[maxn];
    ll dp[maxn];
    ll maxw;
    ll d[maxn], vis[maxn];
    int dijkstra(int mid, int s) {
    	priority_queue<pi, vector<pi>, greater<pi> > q;
    	fill(d + 1, d + n + 1, 0x7fffffffffffffff);
    	d[s] = 0;
    	fill(vis + 1, vis + n + 1, false);
    	q.push(make_pair(d[s], s));
    	while (!q.empty()) {
    		pi now = q.top(); q.pop();
    		int x = now.second;
    		if (vis[x]) continue;
    		vis[x] = true;
    		if (w[x] > mid) continue;
    		for (int i = 0; i < G[x].size(); i++) {
    			int v = G[x][i].v, wi = G[x][i].w;
    			if (d[v] > d[x] + wi && w[v] <= mid && d[x] + wi <= l) {
    				d[v] = d[x] + wi;
    				q.push(make_pair(d[v], v));
    			}
    		}
    	}
    	if (d[t] > l) return 0;
    	else return 1;
    }
    int main() {
    	while (scanf("%lld%lld%lld%lld%lld", &n, &m, &s, &t, &l) != EOF) {
    		maxw = 0;
    		for (int i = 1; i <= n; i++) {
    			w[i] = getnum();
    			maxw = max(maxw, w[i]);
    		}
    		for (int i = 1; i <= n; i++) {
    			G[i].clear();
    		}
    		for (int i = 1; i <= m; i++) {
    			ll a, b; ll wi;
    			a = getnum(), b = getnum(), wi = getnum();
    			adde(a, b, wi);
    		}
    		ll li = 0, r = maxw + 100, mid = -1;
    		ll ans = 0x7fffffffffffffff;
    		while (li <= r) {
    			mid = (li + r) >> 1;
    			if (dijkstra(mid, s)) {
    				r = mid - 1;
    				ans = min(ans, mid);
    			}
    			else li = mid + 1;
    		}
    		if (li > maxw) cout << "-1" << endl;
    		else cout << ans << endl;
    	}
    	return 0;
    }
    /**********************************************************************
    	Problem: 1989
    	User: Artoriax
    	Language: C++
    	Result: AC
    	Time:328 ms
    	Memory:10664 kb
    **********************************************************************/
    
    
  • 相关阅读:
    POJ 3683 Priest John&#39;s Busiest Day (2-SAT+输出可行解)
    Codeforces #2B The least round way(DP)
    避免死锁的银行家算法C++程序实现
    源代码编译安装MySQL5.6.12具体过程
    Android 设计模式
    Java与设计模式-适配器模式
    Java和Flex整合报错(五)
    三层架构—再思考
    怎样让DBGrid在按住Shift点鼠标的同时能将连续范围的多行选中?
    找出你的短板
  • 原文地址:https://www.cnblogs.com/artoriax/p/10372293.html
Copyright © 2011-2022 走看看