• Uva 1599 Ideal Path


    题目大意:

    对于一个n个房间m条路径的迷宫(Labyrinth)(2<=n<=100000, 1<=m<=200000),每条路径上都涂有颜色,颜色取值范围为1<=c<=10^9。求从节点1到节点n的一条路径,使得经过的边尽量少,在这样的前提下,如果有多条路径边数均为最小,则颜色的字典序最小的路径获胜。一条路径可能连接两个相同的房间,一对房间之间可能有多条路径。输入保证可以从节点1到达节点n。

    这题思路很简单但还真没少折腾,前后修改提交了七八次才AC...(也说明自己有多菜了)..

    注意问题:

    1.看清楚原题的输入输出要求,刚了书上的中文题目直接开撸,以为输入输出都是只有一个情况的,所以一开始没加循环导致了WA

    2. bfs要解决重复入队问题,在bfs1中由于一开始的方法导致重复入队,提交后TLE

    3. 将d数组初始化为一个较大的整数 INF = 0x5ffffff ,然后找最小颜色的时候比INF小就修改,提交后WA,原因可能为测试数据中存在颜色号码真的为INF的数据,改为用-1充当INF

    总结:

    1.要看清楚原题的输入输出要求

    2.bfs重复入队问题的解决方法

    3.INF标识尽量用题目不可能出现的数据,如果数据都是正整数,可用-1

    AC代码:

    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <stdio.h>
    #include <algorithm>
    #define maxn 100005
    using namespace std;
    struct ver
    {
    	int next,color;
    	ver(int a,int b) : next(a),color(b) {}
    	ver() {}
    };
    
    vector<ver> G[maxn];
    int vis[maxn];
    int d[maxn];
    int n,m;
    int res[maxn];
    int inque[maxn];
    
    void bfs1()
    {
    	memset(d,-1,sizeof(d));
    	int u,t;
    	queue<int> Q;
    	d[n] = 0;
    	Q.push(n);
    	while(!Q.empty())
    	{
    		t = Q.front(); Q.pop();
    		int sz = G[t].size();
    		for(int i =0; i < sz; ++i)
    		{
    			u = G[t][i].next;
    			if(u == 1)
    			{
    				d[1] = d[t] + 1;
    				return;
    			}
    			if(d[u] == -1)  //未访问过
    			{
    				d[u] = d[t] + 1;
    				Q.push(u);
    			}
    		}
    	}
    }
    
    
    void bfs2()
    {
    	
    	memset(res,0,sizeof(res));
    	memset(inque,0,sizeof(inque));
    	queue<int> Q;
    	int end,clr,minc;
    	int begin = 1;
    	Q.push(begin);
    	while(!Q.empty())
    	{
    		begin = Q.front(); Q.pop();
    		if(begin == n)  return;
    		minc = -1;
    		for(int i = 0; i< G[begin].size(); i++)  //1st  find min color
    		{
    			end = G[begin][i].next;
    			clr = G[begin][i].color;
    			if(d[end] == d[begin]-1)
    			{
    				if(minc == -1) 	minc = clr;
    				else minc = min(minc,clr);
    			}
    		}
    		int index = d[1] - d[begin];  //当前步长
    		if(res[index] == 0)  res[index] = minc;
    		else res[index] = min(res[index],minc);
    		
    		for(int j =  0; j < G[begin].size();j++)	//2st go
    		{
    			end = G[begin][j].next;
    			clr = G[begin][j].color;
    			if(clr == minc && d[end] == d[begin]-1 && !inque[end])
    			{
    				Q.push(end);
    				inque[end] = 1;
    			}
    		}
    
    	}
    }
    
    int main()
    {
    	int a,b,c;
    	while(scanf("%d %d",&n,&m) == 2)
    	{
    		for(int i = 0; i <= n; ++i) G[i].clear();
    		for(int i = 0; i < m; ++i)
    		{
    			scanf("%d %d %d",&a,&b,&c);
    			if(a == b) continue;
    			ver edge1(b,c);
    			ver edge2(a,c);
    			G[a].push_back(edge1);
    			G[b].push_back(edge2);
    		}
    		bfs1();
    		bfs2();
    		
    		printf("%d
    ",d[1]);
    		printf("%d",res[0]);
    		for(int i = 1; i < d[1]; ++i)
    			printf(" %d",res[i]);
    		printf("
    ");	
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    注册验证
    翻页加输入框
    php面向对象
    封装数据库
    浅谈BFC和haslayout
    总结JS面向对象
    总结(JS)
    转载6
    总结(5.30)
    总结(5.29)
  • 原文地址:https://www.cnblogs.com/seanliao/p/8067133.html
Copyright © 2020-2023  润新知