UVa 1599 Ideal Path【BFS】

题意:给出n个点,m条边,每条边上涂有一个颜色,求从节点1到节点n的最短路径,如果最短路径有多条,要求经过的边上的颜色的字典序最小

紫书的思路:第一次从终点bfs,求出各个节点到终点的最短距离,

第二次bfs从起点沿着每到达一个节点d[]减少1来走,按照颜色的字典序最小的路径来走

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include <cmath>
  5 #include<stack>
  6 #include<vector>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<algorithm>
 11 using namespace std;
 12
 13 typedef long long LL;
 14 const int INF = 1000000000;
 15 const int mod=1000000007;
 16 const int maxn=100005;
 17
 18 struct Edge{
 19     int u,v,c;
 20     Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c){}
 21 };
 22
 23 vector<Edge> edges;
 24 vector<int> G[maxn];
 25
 26 void addedges(int u,int v,int c){
 27     edges.push_back(Edge(u,v,c));
 28     int idx=edges.size()-1;
 29     G[u].push_back(idx);
 30 }
 31
 32 int n,vis[maxn],d[maxn];
 33
 34 void rev_bfs(){//求出每一个节点到终点n-1的距离
 35     memset(vis,0,sizeof(vis));
 36     vis[n-1]=true;
 37     d[n-1]=0;
 38
 39     queue<int> q;
 40     q.push(n-1);
 41     while(!q.empty()){
 42         int v=q.front();q.pop();
 43         for(int i=0;i<G[v].size();i++){
 44             int e=G[v][i];
 45             int u=edges[e].v;
 46             if(!vis[u]){
 47                 vis[u]=true;
 48                 d[u]=d[v]+1;
 49                 q.push(u);
 50             }
 51         }
 52     }
 53 }
 54
 55 vector<int> ans;
 56
 57 void bfs(){
 58     memset(vis,0,sizeof(vis));
 59     vis[0]=true;
 60     ans.clear();
 61
 62     vector<int> next;
 63     next.push_back(0);
 64
 65     for(int i=0;i<d[0];i++){
 66         int min_color=INF;
 67         for(int j=0;j<next.size();j++){
 68             int u=next[j];
 69             for(int k=0;k<G[u].size();k++){
 70                 int e=G[u][k];
 71                 int v=edges[e].v;
 72                 if(d[u]==d[v]+1)
 73                 min_color=min(min_color,edges[e].c);
 74             }
 75         }
 76
 77         ans.push_back(min_color);
 78
 79         vector<int> next2;
 80         for(int j=0;j<next.size();j++){
 81             int u=next[j];
 82             for(int k=0;k<G[u].size();k++){
 83                 int e=G[u][k];
 84                 int v=edges[e].v;
 85                 if(d[u]==d[v]+1&&edges[e].c==min_color&&!vis[v]) {
 86                     vis[v]=true;
 87                     next2.push_back(v);
 88                 }
 89             }
 90         }
 91         next=next2;
 92     }
 93
 94     printf("%d\n",ans.size());
 95     printf("%d",ans[0]);
 96     for(int i=1;i<ans.size();i++) printf(" %d",ans[i]);
 97     printf("\n");
 98 }
 99
100 int main(){
101     int m,u,v,c;
102     while(scanf("%d %d",&n,&m)==2){
103         edges.clear();
104         for(int i=0;i<n;i++) G[i].clear();
105
106         while(m--){
107             scanf("%d %d %d",&u,&v,&c);
108             addedges(u-1,v-1,c);
109             addedges(v-1,u-1,c);
110         }
111         rev_bfs();
112         bfs();
113     }
114     return 0;
115 }

这道题放了一个月,最后还是看的标程,艾---看来有些题目不是拖得越久就会了,,,,

不要懒的说啊----

加油--gooooooooooooo---

时间: 2024-10-07 17:24:47

UVa 1599 Ideal Path【BFS】的相关文章

UVa 1599 Ideal Path (两次BFS)

题意:给出n个点,m条边的无向图,每条边有一种颜色,求从结点1到结点n颜色字典序最小的最短路径. 析:首先这是一个最短路径问题,应该是BFS,因为要保证是路径最短,还要考虑字典序,感觉挺麻烦的,并不好做,事实用两次BFS, 第一次是倒序BFS,目的是得到从结点 i 到结点n的最短距离,然后再从第一个点开始到最后一个,要保证在查找时,每经过一点要让d值恰好减少1, 直到终点,这也是一个BFS,因为这个字典序在某个结点是一样的,所以是两个BFS,我超时了好几次,因为少写了一个vis, 一定要细心,

UVA 1599 Ideal Path(双向bfs+字典序+非简单图的最短路+队列判重)

https://vjudge.net/problem/UVA-1599 给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小.一对结点可能有多条边,一条边可能连接相同的结点(自环).输入保证结点1可以到达结点n.颜色是1~10^9的整数. 分析: 从题目中我们可以看出,题目中的无向图是可以出现自环和重边的,自环我们可以在输入的时候检查并排

UVA 1599 Ideal Path(bfs1+bfs2,双向bfs)

给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小.一对结点间可能有多条边,一条边可能连接两个相同结点.输入保证结点1可以达到结点n.颜色为1~10^9的整数. 第一次bfs逆向搜索,得到每个点到终点的最短距离,找出最短路:第二次bfs根据最短距离可以选择满足条件的最短路. 1 #pragma comment(linker, "

UVA 1599 Ideal Path

题意: 给出n和m,n代表有n个城市.接下来m行,分别给出a,b,c.代表a与b之间有一条颜色为c的道路.求最少走几条道路才能从1走到n.输出要走的道路数和颜色.保证颜色的字典序最小. 分析: bfs,先倒搜一次,求出每个点到终点的距离d[i].然后从起点走,每次走到新点保证d-1且颜色最小. 代码: #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #

POJ 3126 Prime Path【BFS】

<题目链接> 题目大意: 给你两个四位数,它们均为素数,以第一个四位数作为起点,每次能够变换该四位数的任意一位,变换后的四位数也必须是素数,问你是否能够通过变换使得第一个四位数变成第二个四位数. 解题分析: 先打一张素数表,然后进行BFS搜索,对于每次搜索的当前数,枚举某一位与它不同的所有数,判断它是否符合条件,如果符合,就将它加入队列,继续搜索. #include<stdio.h> #include<string.h> #include<iostream>

NYOJ592 spiral grid 【BFS】

spiral grid 时间限制:2000 ms  |  内存限制:65535 KB 难度:4 描述 Xiaod has recently discovered the grid named "spiral grid". Construct the grid like the following figure. (The grid is actually infinite. The figure is only a small part of it.) Considering trav

【bfs】【中等难度】tyvj P1234 - bench与奔驰

P1234 - bench与奔驰 From zhangbh001    Normal (OI) 总时限:10s    内存限制:128MB    代码长度 限制:64KB P1234 - bench与奔驰 背景 Background 公园里有个人在练开奔驰 - -!,但是总是撞在bench上 (众人曰:狼来了,快跑啊!) 描述 Description 公园里的bench与奔驰都是无敌的,不会被撞坏.由于开奔驰的人比较"有特点",总是向上下左右四个方向开,而且只会在撞到椅子之后改变方向(

hdoj 1312 Red and Black 【BFS】

题意:一共有四个方向,从'@'出发,找能到达'.'的个数, #是不能通过的. 策略:广搜. 这道题属于最简单的bfs了. 代码: #include<stdio.h> #include<string.h> #include<queue> using std::queue; bool vis[25][25]; char s[25][25]; int n, m; int ans = 0; struct node{ int x, y; }; node st; const int

HDU1242 Rescue 【BFS】

Rescue Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 16314    Accepted Submission(s): 5926 Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is