通往奥格瑞玛的道路,洛谷之提高历练地,最短路问题

正题

      第二题:通往奥格瑞玛的道路

      这道题是求路径上所经过  点的收费最大值    最小。

      没错,要讨论的有两个东西,一个是血量,一个是收费最大,明显我们用一个关键字的最短路解不出来。

      所以我们就会想到将其中一个值二分,以达到满足两个值都符合题意。

代码<如此简单>

#include
#include
#include
#include
using namespace std;

int n,m,k;
int t[10010];
struct edge{
	int y,c,next;
}s[100010];
int len=0;
int mmin=2147483647,mmax;
int blood[10010];
int first[10010];
bool tf[10010];
queue f;

void ins(int x,int y,int c){
	len++;
	s[len].y=y;s[len].c=c;s[len].next=first[x];first[x]=len;
}

bool bfs(int now){
	f.push(1);
	memset(blood,-1,sizeof(blood));
	memset(tf,false,sizeof(tf));
	blood[1]=k;
	while(!f.empty()){
		int x=f.front();
		f.pop();
		tf[x]=true;
		for(int i=first[x];i!=0;i=s[i].next){
			int y=s[i].y;
			if(blood[y]=0 && t[y]<=now){
				blood[y]=blood[x]-s[i].c;
				//if(!tf[y]){
				//	tf[y]=true;
					f.push(y);
			//	}
			}
		}
	}
	if(blood[n]!=-1) return true;
	else return false;
}

int main(){
	scanf("%d %d %d",&n,&m,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&t[i]);
		if(t[i]>mmax) mmax=t[i];
	}
	for(int i=1;i<=m;i++){
		int x,y,c;
		scanf("%d %d %d",&x,&y,&c);
		ins(x,y,c);ins(y,x,c);
	}
	mmin=t[1]>t[n]?t[1]:t[n];
	int ans=-1;
	while(mmin<=mmax)
	{
		int mid=(mmin+mmax)/2;
		if(bfs(mid)){
			mmax=mid-1;
			ans=mid;
		}
		else mmin=mid+1;
	}
	if(ans==-1) printf("AFK");
	else printf("%d",ans);
}

你可能感兴趣的:(通往奥格瑞玛的道路,洛谷之提高历练地,最短路问题)