HDU-3191 How Many Paths Are There 次最短路
2013-10-25 20:06
232 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3191
K短路( 最短路 + A* )
只会求出次短路长度 条数还不懂怎么求 =。=
#include "stdio.h" #include "string.h" #include "vector" #include "queue" using namespace std; const int maxn = 210; const int inf = 1<<30; int n,m,s,e; int dis[maxn][2],cnt[maxn][2],vis[maxn][2]; //dis[i][0]表示到达点i最短路的长度,dis[i][1]表示次短路的长度 //cnt[i][0]表示到达点i最短路的条数,cnt[i][1]表示次短路的条数 struct node { int to,w; node( int a,int b ) { to = a; w = b; } }; vector<node>map[maxn]; struct Node { int v,dis; int mark; //标记最短还是次短 bool operator < ( const Node &p ) const { if( p.dis != dis ) return p.dis < dis; return p.v < v;//这儿如果不按顶点的大小排序,就wa了。 } }; void Dijstra( int s,int e ) { for( int i = 0; i < n; i ++ ) { dis[i][0] = dis[i][1] = inf; cnt[i][0] = cnt[i][1] = 0; } dis[s][0] = 0; cnt[s][0] = 1; memset( vis,0,sizeof(vis) ); priority_queue<Node>que; Node u,v; u.dis = 0; u.mark = 0; u.v = s; que.push( u ); while( !que.empty()) { u = que.top(); que.pop(); if( vis[u.v][u.mark] ) continue; vis[u.v][u.mark] = true; //松驰时有四种情况 for( int i = 0;i < map[u.v].size(); i ++ ) { node x = map[u.v][i]; if( !vis[x.to][0] && dis[x.to][0] > u.dis + x.w ) //找到一个更短的距离,则把原来最短的距离作为次短的距离,同时更新最短的. { if( dis[x.to][0] != inf ) //可能为次短路 { v.v = x.to; v.dis = dis[x.to][0]; v.mark = 1; dis[x.to][1] = dis[x.to][0]; cnt[x.to][1] = cnt[x.to][0]; que.push( v ); } dis[x.to][0] = u.dis + x.w; cnt[x.to][0] = cnt[u.v][u.mark]; v.v = x.to; v.dis = dis[x.to][0]; v.mark = 0; que.push( v ); } else if( !vis[x.to][0] && dis[x.to][0] == u.dis + x.w ) cnt[x.to][0] += cnt[u.v][u.mark]; else if( !vis[x.to][1] && dis[x.to][1] > u.dis + x.w )//不可以更新最短距离,但可以更新次短的 { dis[x.to][1] = u.dis + x.w; cnt[x.to][1] = cnt[u.v][u.mark]; v.v = x.to; v.dis = dis[x.to][1]; v.mark = 1; que.push( v ); } else if( !vis[x.to][1] && dis[x.to][1] == u.dis + x.w )//找到一条新的相同距离的次短路 cnt[x.to][1] += cnt[u.v][u.mark]; } } } int main() { int a,b,c; //freopen( "data.txt","r",stdin ); while( scanf("%d%d%d%d",&n,&m,&s,&e) == 4 ) { for( int i = 0; i < n; i ++ ) map[i].clear(); for( int i = 1; i <= m; i ++ ) { scanf("%d%d%d",&a,&b,&c); map[a].push_back( node(b,c) ); } Dijstra( s,e ); printf("%d %d\n",dis[e][1],cnt[e][1]); } return 0; }
K短路( 最短路 + A* )
只会求出次短路长度 条数还不懂怎么求 =。=
#include<stdio.h> #include<string.h> #include<vector> #include<queue> using namespace std; const int maxn = 210; const int inf = 1<<29; int n,m,s,e; int dis[maxn],outque[maxn],vis[maxn]; struct node { int id,w; node( int a,int b ) { id = a; w = b; } }; struct Node { int to; int g,f; bool operator < ( const Node &r ) const { if( r.f == f ) return r.g < g; return r.f < f; } }; vector<node>map[maxn],maps[maxn]; bool SPEA( int s ) { queue<int>que; memset( outque,0,sizeof(outque) ); memset( vis,0,sizeof(vis) ); for( int i = 0; i < n; i ++ ) dis[i] = inf; dis[s] = 0; que.push( s ); vis[s] = true; while( !que.empty() ) { int x = que.front(); que.pop(); vis[x] = false; outque[x] ++; if( outque[x] > n ) return false; for( int i = 0; i < map[x].size(); i ++ ) { node u = map[x][i]; if( u.w != inf && dis[u.id] > dis[x] + u.w ) { dis[u.id] = dis[x] + u.w; if( !vis[u.id] ) { vis[u.id] = true; que.push( u.id ); } } } } return true; } int Astar( int start,int end,int k ) { Node e,u; int cnt = 0; //标记终点出队次数 priority_queue<Node>que; if( start == end ) k ++; if( dis[start] == inf ) return -1; e.to = start; e.g = 0; e.f = e.g + dis[e.to]; que.push(e); while( !que.empty() ) { e = que.top(); que.pop(); if( e.to == end ) cnt ++; if( cnt == k ) { return e.g; } for( int i = 0; i < maps[e.to].size(); i ++ ) { node v = maps[e.to][i]; u.to = v.id; u.g = e.g + v.w; u.f = u.g + dis[u.to]; que.push(u); } } return -1; } int main() { freopen("data.txt","r",stdin); int a,b,c; while( scanf("%d%d%d%d",&n,&m,&s,&e) == 4 ) { for( int i = 1; i <= m; i ++ ) { scanf("%d%d%d",&a,&b,&c); maps[a].push_back( node(b,c) ); map[b].push_back( node(a,c) ); } SPEA( e ); int ans = Astar( s,e,2 ); printf("%d\n",ans); } return 0; }
相关文章推荐
- USB 2.0 suspend resume
- win7 32/64位安装MySQL详细步骤(图文)
- linux下C 编程学习之多进程编程(一)
- 悉心沉淀,耐心坚持!
- 现代程序设计 作业6
- Dom4J操作XML
- 半数集问题
- 1.2 auth2.0
- 单链表查找倒数第K个节点
- 选择性求面积
- 【leetcode】Candy
- java提高篇(七)-----详解内部类
- java提高篇(七)-----详解内部类
- java
- poj3126
- POJ 3122 Pie 二分枚举
- Application、Activity Stack 和 Task的区别
- HDU 1527 取石子游戏 威佐夫博奕
- Oracle学习笔记1--sqlplus常用命令
- Vim命令合集