大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层。跑完一层就会得到这层最小的color号。

反省:这道题由于有自环和重边的存在,因此满足条件的一个点可能多次被加到队列,这样的复杂度将会成指数级。没注意到这点TLE了几发。。。如果一个点到另一个点的最短路径只有一条,就不用判断重复了。正是因为重边所以特别需要注意这点

示意图:

学习点:

1.层次图的构建,逆向思维。

2.注意不是简单图的情况,重边和自环。

3.搜索最致命的问题就是状态判重

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue> //#define local
using namespace std;
const int INF = 1e9;
const int maxm = 2e5 + ;
const int maxn = 1e5 + ;
int n; struct Edge
{
int v,c,nxt;
}e[maxm<<]; int d[maxn];
int cnt , head[maxn]; //init head -1
inline void addEdge(int u,int v,int c)
{
// e[cnt].u = u;
e[cnt].v = v;
e[cnt].c = c;
e[cnt].nxt = head[u];
head[u] = cnt++;
} void bfs()
{
queue<int> q;
memset(d,-,sizeof(d));
q.push(n); d[n] = ;
int u,v,i;
while(!q.empty()){
u = q.front(); q.pop();
if(u == ) { printf("%d\n",d[u]); return ;}
for(i = head[u]; ~i ; i = e[i].nxt ){
v = e[i].v;
if(~d[v]) continue;
d[v] = d[u] + ;
q.push(v);
}
}
} bool vis[maxn];
void bfs2()
{
queue<int> q;///复杂度写高了 没有给结点判断重复 指数级
int u = ,v, i;
q.push(u);
int c = INF;//最小color
vector<int> vec;//保存下一个层次的点
memset(vis,false,sizeof(vis));
while(!q.empty()||!vec.empty()) { if(q.empty()) { //保证队列里只有一个层次的点,如果队列空了,说明上一层的点都跑完了,这时候c一定是最小的
for(i = ;i < vec.size();i++) {
int k = vec[i], v = e[k].v;
if(e[k].c == c && !vis[v] ) {//vis[v] 重边
if(e[k].v == n) { printf("%d\n",c); return ;}
q.push(e[vec[i]].v); vis[v] = true;
}
}
vec.clear();
printf("%d ",c); c = INF;
} u = q.front(); q.pop(); for(i = head[u]; ~i ; i = e[i].nxt ) {
v = e[i].v;
if(d[u] - d[v] == && e[i].c <= c) {
vec.push_back(i);
c = e[i].c;
}
}
}
} int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local
int m;
int u,v,c;
while(~scanf("%d%d",&n,&m)){
memset(head,-,sizeof(head)); cnt = ;
while(m--) {
scanf("%d%d%d",&u,&v,&c);
if(u == v) continue;//忽略自环
addEdge(u,v,c);
addEdge(v,u,c);
}
bfs();
bfs2();
}
return ;
}

UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)的更多相关文章

  1. UVa 1599 Ideal Path (两次BFS)

    题意:给出n个点,m条边的无向图,每条边有一种颜色,求从结点1到结点n颜色字典序最小的最短路径. 析:首先这是一个最短路径问题,应该是BFS,因为要保证是路径最短,还要考虑字典序,感觉挺麻烦的,并不好 ...

  2. POJ 3126 Prime Path 素数筛,bfs

    题目: http://poj.org/problem?id=3126 困得不行了,没想到敲完一遍直接就A了,16ms,debug环节都没进行.人品啊. #include <stdio.h> ...

  3. POJ 3216 Prime Path(打表+bfs)

    Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27132   Accepted: 14861 Desc ...

  4. 理想路径——双向BFS

    题目 给n个点m条边(2 ≤ n ≤ 100000,1 ≤ m ≤ 200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量的少,在此前提下,经过边的颜色序列的 ...

  5. POJ 3126 Prime Path 解题报告(BFS & 双向BFS)

    题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...

  6. POJ 3126 Prime Path 简单广搜(BFS)

    题意:一个四位数的质数,每次只能变换一个数字,而且变换后的数也要为质数.给出两个四位数的质数,输出第一个数变换为第二个数的最少步骤. 利用广搜就能很快解决问题了.还有一个要注意的地方,千位要大于0.例 ...

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

    题目大意: 对于一个n个房间m条路径的迷宫(Labyrinth)(2<=n<=100000, 1<=m<=200000),每条路径上都涂有颜色,颜色取值范围为1<=c&l ...

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

    https://vjudge.net/problem/UVA-1599 给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色 ...

  9. POJ 3126 Prime Path(素数路径)

    POJ 3126 Prime Path(素数路径) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 The minister ...

随机推荐

  1. strlen细节以及sizeof细节

    strlen细节以及sizeof细节前者会忽略结束符号,后者不会忽略结束符

  2. POJ 2976 Dropping tests (二分+贪心)

    题意:给定 n 个分数,然后让你去年 m 个分数,使得把剩下的所有的分子和分母都相加的分数最大. 析:这个题并不是分子越大最后结果就越大,也不是整个分数越大,最后结果就越大的,我们可以反过来理解,要去 ...

  3. Socket()与WSASocket()的区别

    socket()   创建一个通讯端点并返回一个套接口.但是在socket库中例程在应用于阻塞套接口时会阻塞.     WSASocket()的发送操作和接收操作都可以被重叠使用.接收函数可以被多次调 ...

  4. HRBUST - 1214 NOIP2000提高组 方格取数(多线程dp)

    方格取数 设有N*N的方格图(N<=10),我们将其中的某些方格中填入正整数,而其他的方格中则放人数字0.如下图所示(见样例 ,黄色和蓝色分别为两次走的路线,其中绿色的格子为黄色和蓝色共同走过的 ...

  5. SQL SERVER动态列名

    在ms sql server实现动态呈现列的方法很多.下面Insus.NET解决也算是另外一种参考. 如: 准备实现功能的数据: ) NOT NULL PRIMARY KEY) INSERT INTO ...

  6. List Control控件中及时捕获checkbox被选中的消息的解决方案

    转自:http://blog.csdn.net/vycode/article/details/7345073 我的功能需求是:用户可以在List Control里添加item,当无选项被选中(即Che ...

  7. [转] ios数组基本用法和排序

    http://blog.csdn.net/daiyelang/article/details/18726947 1.创建数组 // 创建一个空的数组 NSArray *array = [NSArray ...

  8. SVN Trunk Tag Branch

    http://blog.csdn.net/vbirdbest/article/details/51122637

  9. Linux常用命令(补充)--其他

    其他1)记录命令历史(1)!! (连续两个”!”),表示执行上一条指令:(2)!n(这里的n是数字),表示执行命令历史中第n条指令,例如”!100”表示执行命令历史中第100个命令:(3)!字符串(字 ...

  10. Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器

    ---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...