• 【解题报告】 洛谷P1462 通往奥格瑞玛的道路


    【解题报告】 洛谷P1462 通往奥格瑞玛的道路

    题目背景

    在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量

    有一天他醒来后发现自己居然到了联盟的主城暴风城

    在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛

    题目描述

    在艾泽拉斯,有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。

    输入输出样例

    输入 #1

    4 4 8
    8
    5
    6
    10
    2 1 2
    2 4 1
    1 3 4
    3 4 3
    

    输出 #1

    10
    

    说明/提示

    对于60%的数据,满足n≤200,m≤10000,b≤200

    对于100%的数据,满足n≤10000,m≤50000,b≤1000000000

    对于100%的数据,满足ci≤1000000000,fi≤1000000000,可能有两条边连接着相同的城市。

    思路

    二分答案,单源最短路径

    直接对于花费进行二分答案,套用Dijkstra堆优化的模板,对于花费进行剪枝

    代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <queue>
    using namespace std;
    const int N=10010,M=100010;
    int n,m,b,cost;
    int f[N];
    int head[N],ver[M],edge[M],next[M],d[N],tot;
    bool v[N];
    priority_queue <pair<int,int> > q;
    void add(int x,int y,int z)
    {
    	ver[++tot]=y,edge[tot]=z,next[tot]=head[x],head[x]=tot;
    }
    bool dijkstra(int k)
    {
    	if(k<f[1]) return false;
    	for(int i=1;i<=n;i++)
    	d[i]=1e9;
    	memset(v,0,sizeof(v));
    	d[1]=0;
    	q.push(make_pair(0,1));
    	while(q.size())
    	{
    		int x=q.top().second;
    		q.pop();
    		if(v[x]) continue;
    		v[x]=1;
    		for(int i=head[x];i;i=next[i])
    		{
    			int y=ver[i],z=edge[i];
    			if(f[y]<=k&&v[y]==0&&d[y]>d[x]+z)
    			{
    				d[y]=d[x]+z;
    				q.push(make_pair(-d[y],y));  
    			}
    		}
    	}
    	return d[n]<b;
    }
    int main()
    {
    	cin>>n>>m>>b;
    	for(int i=1;i<=n;i++)
    	cin>>f[i];
    	for(int i=1;i<=m;i++)
    	{
    		int x,y,z;
    		cin>>x>>y>>z;
    		add(x,y,z); add(y,x,z);
    	}
    	if(!dijkstra(1e9))
    	{
    		cout<<"AFK"<<endl;
    		return 0;
    	}
    	int l=1,r=1e9;
    	while(l<=r)
    	{
    		int mid=(l+r)/2;
    		if(dijkstra(mid)) r=mid-1;
    		else l=mid+1;
    	}
    	cout<<l<<endl;
    	return 0;
    }
    
  • 相关阅读:
    推荐下自己的开源框架:DataMapFramework
    真的能无师自通吗?JAVA学习指导系列
    再回首,工作的第一个十年
    2个DataSet中的数据传递问题,请高手们多多指教。
    数据结构小结
    CDQZ_Training 2012524 词编码
    PowerDesigner显示Comment注释
    DDD基本元素
    使用FluorineFx.NET更新FMS中的SharedObject
    如何取消页面缓存
  • 原文地址:https://www.cnblogs.com/wweiyi2004/p/13928905.html
Copyright © 2020-2023  润新知