一句话题解:
不会用题解写的做。。。
题意:给你一个图,每条边有一个价值。从1走到n,每次路径的价值发生变化花费就会+1,问最少花费。如果走不到n点输出-1。
思路:bfs搜索,每走到一个点入队。每次取队首元素出队,dfs该结点能走到的所有不需要花费的结点(路径价值与之前的相同),如果该结点未被访问过则更新花费,并入队。
到n的最短路一定会先被搜索到,因为bfs每次的花费都在增加。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
int cnt,head[100000+10];
struct node
{
int to,nxt,w;
}edge[200000*4+10];
void add(int u,int v,int w)
{
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
int dis[100000+10],vis[100000+10];
queue<int>q;
void dfs(int rt,int w,int di)
{
q.push(rt);
for(int i=head[rt];~i;i=edge[i].nxt)
{
if(edge[i].w==w&&vis[edge[i].to]==0)
{
vis[edge[i].to]=1;
dis[edge[i].to]=di;
dfs(edge[i].to,w,di);
}
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
cnt=0;
memset(head,-1,sizeof head);
memset(vis,0,sizeof vis);
for(int i=0;i<=n;i++) dis[i]=1e9;
while(!q.empty()) q.pop();
for(int i=0;i<m;i++)
{
int u,v,w;scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
q.push(1);
dis[1]=0;
vis[1]=1;
while(!q.empty())
{
int rt=q.front();
//printf("%d----\n",rt);
q.pop();
for(int i=head[rt];~i;i=edge[i].nxt)
{
int to=edge[i].to;
if(vis[to]==1)continue;
vis[to]=1;
dis[to]=dis[rt]+1;
dfs(to,edge[i].w,dis[rt]+1);
}
if(dis[n]!=1e9)break;
}
//for(int i=1;i<=n;i++)printf("%d\n", dis[i]);
if(dis[n]==1e9)printf("-1\n");
else printf("%d\n", dis[n]);
}
return 0;
}