HDU 6386 Age of Moyu(搜索)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/PK__PK/article/details/81664714