极其简单的最短路问题

极其简单的最短路问题

题目

小C终于被小X感动了,于是决定与他看电影,然而小X距离电影院非常远,现在假设每条道路需要花费小X的时间为1,由于有数以万计的好朋友沿路祝贺,导致小X在通过某些路不得不耗费1的时间来和他们聊天,尽管他希望尽早见到小C,所以他希望找到一条最快时间到达电影院的路。

一开始小X在1号点,共有N个点,M条路,电影院为T号点。

输入

第一行2个正整数,分别为n,m,t
以下m行,每行3个数,表示连接的编号以及权值
(注意,可能会有重边)

输出

一行一个数,表示1到t的最短路

输入样例

10 12 6
3 9 2
6 9 2
6 2 1
3 1 1
1 9 2
2 8 2
7 10 1
7 2 1
10 0 1
8 1 1
1 5 2
3 7 2

输出样例

4

数据范围

30%:n<=10 m<=20
60%: n<=1000 m<=20000
100%: n<=5000000 m<=10000000

思路

这道题看起来是一道最短路题,但是如果用最短路做会超时,那怎么办呢?

由题目可得,边的权值只有可能是1或者2。
那么我们可以把权值为2的边转换为权值为1的两条边,比如这样:
1 − > 2 1->2 1>2 变成 1 − > 3 − > 2 1->3->2 1>3>2
那么这样,我们就可以用 b f s bfs bfs来做了。

代码

#include
#include
using namespace std;
struct note
{
	int to,next;
}e[20000001];
int n,m,t,le[40000001],k,x,y,z,f[40000001];
bool in[40000001];
int read()//快读
{
	int ans=0;
	char c=getchar();
	while (c>='0'&&c<='9')
	{
		ans=ans*10+c-48;
		c=getchar();
	}
	return ans;
}
void jl(int xx,int yy)//建邻接表
{
	e[++k]=(note){yy,le[xx]};
	le[xx]=k;
	e[++k]=(note){xx,le[yy]};
	le[yy]=k;
}
void bfs()//bfs
{
	in[1]=1;
	queue<int>a;
	a.push(1);
	while (!a.empty())
	{
		int h=a.front();
		a.pop();
		for (int i=le[h];i;i=e[i].next)
		if (!in[e[i].to])
		{
			a.push(e[i].to);
			in[e[i].to]=1;
			f[e[i].to]=f[h]+1;
		}
		if (in[t])
		{
			printf("%d",f[t]);
			return ;
		}
	}
}
int main()
{
	n=read();m=read();t=read();//读入
	for (int i=1;i<=m;i++)
	{
		x=read();y=read();z=read();//读入
		if (z==1) jl(x,y);//建邻接表
		else//把权值为二的边转化成两条边
		{
			jl(x,++n);
			jl(n,y);
		}
	}
	bfs();//bfs
	return 0;
}

你可能感兴趣的:(#,dfs或bfs)