极其简单的最短路问题
题目大意:
求最短路,权值只有1或2
原题:
题目描述
小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
解题思路:
看上去是一个最短路模板
但数据太大把最短路给卡掉了
所以我们把长度为2的改为连接一个其他的点,间接的连接(如图)
然后bfs就行了
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,t,h,xx,yy,tot,head[15000005],p[15000005],b[15000005];
struct rec
{int to,next;
}a[10000005];
int read()//快读
{char x=getchar();int d=1,l=0;while (x<'0'||x>'9') {if (x=='-') d=-1;x=getchar();}while (x>='0'&&x<='9') l=(l<<3)+(l<<1)+x-48,x=getchar();return l*d;
}
void lj(int xxx,int yyy)//连接两个点
{a[++tot].to=yyy;a[tot].next=head[xxx];head[xxx]=tot;a[++tot].to=xxx;a[tot].next=head[yyy];head[yyy]=tot;
}
void bfs()
{p[1]=1;queue<int>d;d.push(1);while (!d.empty()){h=d.front();d.pop();for (int i=head[h];i;i=a[i].next)if (!p[a[i].to]) d.push(a[i].to),p[a[i].to]=1,b[a[i].to]=b[h]+1;//bfsif (p[t]){printf("%d",b[t]);return;}}
}
int main()
{n=read();m=read();t=read();for (int i=1;i<=m;++i){xx=read();yy=read();if (read()&1) lj(xx,yy);//连接else lj(xx,++n),lj(n,yy);}bfs();
}