• P1462 通往奥格瑞玛的道路(二分+dijkstra)


    题目背景

    在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量
    有一天他醒来后发现自己居然到了联盟的主城暴风城
    在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛

    题目描述

    在艾泽拉斯,有n个城市。编号为1,2,3,...,n。
    城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。
    每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。
    假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的。
    歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。

    输入格式

    第一行3个正整数,n,m,b。分别表示有n个城市,m条公路,歪嘴哦的血量为b。
    接下来有n行,每行1个正整数,fi。表示经过城市i,需要交费fi元。
    再接下来有m行,每行3个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市ai和城市bi之间有一条公路,如果从城市ai到城市bi,或者从城市bi到城市ai,会损失ci的血量。

    输出格式

    仅一个整数,表示歪嘴哦交费最多的一次的最小值。
    如果他无法到达奥格瑞玛,输出AFK。

    二分答案,每次跑一边dijkstra,如果如果某一个城市的收费大于二分的值就跳过它。最后到n的最短路小于b即为合法。
    下面代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define pii pair<ll,int>
    using namespace std;
    
    ll n,m,b,f[10010];
    struct Edge{
    	int to,next;
    	ll w;
    }edge[100010];
    int h[10010],tot;
    void add(int u,int v,ll w){
    	edge[++tot].w = w;
    	edge[tot].to = v;
    	edge[tot].next = h[u];
    	h[u] = tot; 
    }
    priority_queue<pii> q;
    ll vis[10010],dis[10010]; 
    ll dijk(ll mid){
    	for(int i = 1; i <= n; ++i){
    		dis[i] = 0x3f3f3f3f;
    		vis[i] = 0;
    	}
    	dis[1] = 0;
    	q.push(make_pair(0,1));
    	while(!q.empty()){
    		int p = q.top().second;
    		q.pop();
    		if(vis[p]) continue;
    		vis[p] = 1;
    		for(int i = h[p]; i; i = edge[i].next){
    			int v = edge[i].to;
    			if(f[v] > mid) continue;
    			if(dis[v] > dis[p] + edge[i].w){
    				dis[v] = dis[p] + edge[i].w;
    				if(!vis[v]) q.push(make_pair(-dis[v],v));
    			}
    		}
    	}
    	return dis[n];
    }
    
    int main(){
    	cin >> n >> m >> b;
    	ll l = 0,r = 0; 
    	for(int i = 1; i <= n; ++i){
    		scanf("%lld",&f[i]);
    		r = max(r,f[i]);
    	}
    	for(int i = 1; i <= m; ++i){
    		int a,b; ll c;
    		scanf("%d%d%lld",&a,&b,&c);
    		add(a,b,c);
    		add(b,a,c);
    	}
    	if(dijk(r) >= b){
    		cout << "AFK" << endl;
    		return 0;
    	}
    	while(l < r){
    		ll mid = (l + r) >> 1;
    		if(dijk(mid) < b) r = mid;
    		else l = mid + 1;
    	}
    	cout << l << endl;
    	return 0;
    }
    
  • 相关阅读:
    python struct使用
    pythonunittest(1)
    python os.path模块学习(转)
    pythonunittest(2)
    主机+虚拟机Ubuntu+开发板互相ping通
    wince 外部中断调用可安装ISR错误(data abort)
    wince firstboot.nb0 的大小的问题解决
    wince 串口索引超过10个解决方法
    wince uboot 启动 wince
    zigbee 天线的设计
  • 原文地址:https://www.cnblogs.com/FoxC/p/11379767.html
Copyright © 2020-2023  润新知