理想路径,P173Uva1599
来源:互联网 发布:民国报纸数据库 编辑:程序博客网 时间:2024/05/21 09:01
这也是一道非常好的无向图最短路问题。其中在边上增加了颜色条件,使得稍微复杂一些。刘的此篇代码使我在无向图最短路的算法实现上有很大的收获。下面直接进行干货总结:
语法细节:
1.结构体的无参构造函数:
struct Edge {
int u, v, c;
Edge(int u=0, int v=0, int c=0):u(u),v(v),c(c) {}
};
2.任何结构体和类都可以无对象实体传参。
edges.push_back(Edge(u, v, c));//语法积累
算法思路:
1.图的存储。自己过去对于图的存储仅仅理解为数组的形式。尽管关于本题可以用一个二维数组来记录arr[n1][n2] = color;但是此种存储的弊端是仅仅记录了点与点之间相连,但是无法快速查找与节点n相连的节点有哪个。因此在遍历搜索的时候,时间复杂度大大提高。而刘却解决了此问题。刘将所有的路径信息保存在一个结构体数组中,然后再将结构体数组中从n出发的边的位置记录在G[n]之中,这样就在图的存储的时候记录下了每个节点的相邻节点,为之后的遍历打下了基础。
2.求连通分之用DFS,求最短路用BFS。DFS用递归,BFS用队列。但是无论DFS还是BFS图的遍历一定要有标记数组,防止查重。
3.先反向BFS,从求出每个节点到目标节点的最短距离。
4.然后在正向BFS从起点开始走,对它的连接节点做两次遍历,第一次查找到目标节点最短距离比它少1的节点中最小的颜色,第二次在遍历一遍,把符合这两个条件(1.到目标节点最短距离比它少1。2.节点颜色是刚才查找出的最小颜色)的节点入队。
5.继续BFS出结果。
// UVa1599 Idea Path// Rujia Liu#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;const int maxn = 100000 + 5;const int INF = 1000000000; // maximal colorstruct Edge { int u, v, c; Edge(int u=0, int v=0, int c=0):u(u),v(v),c(c) {}};vector<Edge> edges;vector<int> G[maxn];void AddEdge(int u, int v, int c) { edges.push_back(Edge(u, v, c));//语法积累 int idx = edges.size() - 1; G[u].push_back(idx);}int n, vis[maxn];int d[maxn];// reverse bfs to find out the distance from each node to n-1void rev_bfs() { memset(vis, 0, sizeof(vis)); d[n-1] = 0; vis[n-1] = true; queue<int> q; q.push(n-1); while(!q.empty()) { int v = q.front(); q.pop(); for(int i = 0; i < G[v].size(); i++) { int e = G[v][i]; int u = edges[e].v; if(!vis[u]) { vis[u] = true; d[u] = d[v] + 1; q.push(u); } } }}vector<int> ans;// forward bfs to construct the pathvoid bfs() { memset(vis, 0, sizeof(vis)); vis[0] = true; ans.clear(); vector<int> next; next.push_back(0); for(int i = 0; i < d[0]; i++) { int min_color = INF; for(int j = 0; j < next.size(); j++) { int u = next[j]; for(int k = 0; k < G[u].size(); k++) { int e = G[u][k]; int v = edges[e].v; if(d[u] == d[v] + 1) min_color = min(min_color, edges[e].c); } } ans.push_back(min_color); // find out the next vertices of the next phase vector<int> next2; for(int j = 0; j < next.size(); j++) { int u = next[j]; for(int k = 0; k < G[u].size(); k++) { int e = G[u][k]; int v = edges[e].v; if(d[u] == d[v] + 1 && !vis[v] && edges[e].c == min_color) { vis[v] = true; next2.push_back(v); } } } next = next2; } printf("%d\n", ans.size()); printf("%d", ans[0]); for(int i = 1; i < ans.size(); i++) printf(" %d", ans[i]); printf("\n");}int main() { int u, v, c, m; while(scanf("%d%d", &n, &m) == 2) { for(int i = 0; i < n; i++) G[i].clear(); while(m--) { scanf("%d%d%d", &u, &v, &c); AddEdge(u-1, v-1, c); AddEdge(v-1, u-1, c); } rev_bfs(); bfs(); } return 0;}
- 理想路径,P173Uva1599
- UVA 1599 理想路径
- 高级技术人才理想成长路径
- 例题6-20 理想路径 UVa1599
- 理想路径(Ideal Path,UVa 1599)
- UVA 1599 Ideal Path (理想路径)
- 理想
- 理想
- 理想
- 理想
- 理想
- 理想
- 理想
- 理想
- 理想
- 理想
- 理想
- 理想
- Artificial Intelligence
- 进程和线程关系及区别
- 懒加载
- Java基础之正则表达式
- 错误信息:ids for this class must be manually assigned before calling save(): sample.db.Completedsample
- 理想路径,P173Uva1599
- nginx concat模块安装配置
- flask 中使用 装饰器
- Spring Cloud | 第二篇:服务消费者(Ribbon)
- html5 postMessage解决跨域、跨窗口消息传递
- java多线程 关于synchronized wait notify CountDownLatch CyclicBarrier Semaphore
- 邂逅ReactNative(二):使用Eslint规范项目代码
- Spark 2.0从入门到精通245讲——操作RDD(transformation案例实战)
- java后台发送请求并获取返回值