版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/PK__PK/article/details/81664714
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6386
题意:n个点,m条边,每条边有权值,双向边。你要从1走到n,若路径上的权值一样,则只用花费1即可到达,若当前边的路径和上一条边的路径不一样,就多花费1.
例如1 - 1- 1 全是1所以花费为1.
1-2-1,权值变化了2次所以花费为3。
题解:通过bfs来找到最短路径上的节点v,然后通过dfs来找到与节点v相连的点v‘中那些权值一样,然后加入bfs的搜索队列当中。
搜到n就是正确结果
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n,m,cas,ans;
int dis[N],head[N],look[N];
queue<int> q;
struct Edge{
int u,v,w,next,vis;
}edge[N*4];
void add_edge(int u,int v,int w){
edge[cas].u = u;
edge[cas].v = v;
edge[cas].w = w;
edge[cas].next = head[u];
edge[cas].vis = 0;
head[u] = cas++;
}
void dfs(int rt,int cl,int num){
int i,j;
if(rt == n){
ans = num;
return ;
}
if(!look[rt]){
look[rt] = 1;
dis[rt] = num;
q.push(rt);
}
for(i = head[rt] ; i != -1 ; i = edge[i].next){
if(edge[i].vis) continue;
if(edge[i].w == cl){
edge[i].vis = 1;
dfs(edge[i].v,cl,num);
}
}
return ;
}
int bfs(){
int i,j,v;
while(!q.empty()) q.pop();
q.push(1);
dis[1] = 0;
look[1] = 1;
while(!q.empty()){
int now = q.front();
q.pop();
for(i = head[now] ; i != -1 ; i = edge[i].next){
if(edge[i].vis) continue;
v = edge[i].v;
edge[i].vis = 1;
dfs(v,edge[i].w,dis[now]+1);
if(ans > 0) break;
}
if(ans > 0) break;
}
return ans ;
}
int main(){
while(~scanf("%d%d",&n,&m)){
int i,j;
cas = 0;
memset(head,-1,sizeof(head));
memset(look,0,sizeof(head));
memset(dis,0x3f3f3f3f,sizeof(dis));
for(int i = 1 ; i <= m ; i ++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
ans = -1;
ans = bfs();
printf("%d\n",ans);
}
return 0;
}