SCU 4444 Travel(bfs)

本文探讨了在一个由城镇组成的国家中寻找从城镇1到城镇n的最短旅行时间问题。该问题涉及高速公路和铁路两种交通方式,每种方式对应不同的旅行时间。文章提供了具体的解决思路及代码实现。

Travel

The country frog lives in has nn towns which are conveniently numbered by 1,2,,n1,2,…,n.

Among n(n1)2n(n−1)2 pairs of towns, mm of them are connected by bidirectional highway, which needs aa minutes to travel. The other pairs are connected by railway, which needs bb minutes to travel.

Find the minimum time to travel from town 11 to town nn.

Input

The input consists of multiple tests. For each test:

The first line contains 44 integers n,m,a,bn,m,a,b (2n105,0m5105,1a,b1092≤n≤105,0≤m≤5⋅105,1≤a,b≤109). Each of the following mm lines contains 22 integers ui,viui,vi, which denotes cities uiui and vivi are connected by highway. (1ui,vin,uivi1≤ui,vi≤n,ui≠vi).

Output

For each test, write 11 integer which denotes the minimum time.

Sample Input

    3 2 1 3
    1 2
    2 3
    3 2 2 3
    1 2
    2 3

Sample Output

    2
    3

题解:
若1到n没有高铁,则判断1到n坐高铁和b的大小关系,
如果有高铁并且a>b则判断有没有一个点通过普通铁路连接
1和n两点,若有则判断a和2*b的关系
代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#define  ll long long
using namespace std;
int n,m;
ll a,b;
vector<int>v[100005];
struct node
{
	int v;
	ll t;
};
queue<node>q;
bool bo[100005];
ll min1(ll a,ll b)
{
	if(a>b)return b;
	return a;
}
int main()
{
	while(~scanf("%d %d %lld %lld",&n,&m,&a,&b))
	{
		while(!q.empty()) q.pop();
		for(ll i=0;i<100005;i++) v[i].clear();
		memset(bo,0,sizeof(bo));
		bool bb=0;
		for(ll i=1;i<=m;i++)
		{
			int x,y;
			scanf("%d %d",&x,&y);
			v[x].push_back(y);
			v[y].push_back(x);
			if((x==1&&y==n)||(x==n&&y==1))bb=1;
		}
		if(a>=b)
		{
			if(bb==0)printf("%d\n",b);
			else
			{
				for(int i=2;i<n;i++)
				{
					bool is=0;
					for(int j=0;j<v[i].size();j++)
					{
						if(v[i][j]==1||v[i][j]==n)is=1;
					}
					if(is==0)
					{
						bb=0;break;
					}
				}
				if(bb==0)printf("%d\n",min(a,2*b));
				else printf("%d\n",a);
			}
			continue;
		}
		node s;
		s.v=1;
		s.t=0;
		q.push(s);
		ll mx=b;
		bo[1]=1;
		bool f=0;
		while(!q.empty())
		{
			node s;
			s=q.front();
			q.pop();
			for(int i=0;i<v[s.v].size();i++)
			{
				int y=v[s.v].at(i);
				if(bo[y]) continue;
				if(y==n)
				{
					mx=min1(mx,(s.t+1)*a);
					f=1;
					break;
				}
				node ss;
				ss.t=s.t+1;
				ss.v=y;
				q.push(ss);
			}
			if(f)break;
		}
		printf("%lld\n",mx);
	}
	return 0;
}

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值