hdu6181-启发式搜索A*|次短路模板|最短路枚举-Two Paths
来源:互联网 发布:分期网站源码 编辑:程序博客网 时间:2024/05/22 17:43
acm.hdu.edu.cn/showproblem.php?pid=6181
我是用次短路板子做的。。初始化得多点不然得超时。
①求次短路的思路是维护到达x点的最小距离和次小距离。(dij和spfa应该都可以,都做一下板子)
② 用A*,即启发式搜索,先求出F(X)即x点到目的点的代价,在求S(x),即初始点到x点的代价,然后找第k小的。用muliset或者优先队列都行,(multiset写了好一会。。)
③ 求出最短路后,枚举。。这个我没敢弄,因为怕超时。O(VE)
* 我A*的理解:一般的搜索都是闭着眼搜索,随便搜索,枚举所有的状态,有的花费巨大且是坑,但是也要试一遍。效率不高。
而A*则预先计算当前状态到目的状态的花费,找最小的试,
贼好。正面计算 初始点到当前状态的话费时,像bfs,但是比bfs高效的原因就是因为前面的就记录(不记录爆搜的话mle)
先计算了D,在遍历F,
#include <bits/stdc++.h>using namespace std;/* multiset 或者优先队列,都是可以的,,好像qwq*//* */typedef long long ll;typedef pair<ll,int> pii;const long long INF=1e14;const int maxn=1e5;struct Node{ int to;ll w; Node(){}; Node(int _a,ll _b){to=_a;w=_b;};};ll dis[maxn];struct qNode{ int to; ll w; qNode(){}; qNode(ll _a,int _b){to=_b;w=_a;}; friend bool operator <(qNode a,qNode b){ return a.w+dis[a.to]<b.w+dis[b.to];// 返回最小的。这个很重要,A*的重点(敲屏幕) }};//记录D(x)vector<Node>G[maxn];multiset<qNode>mul;void add(int u,int v,long long w){ G[u].push_back(Node(v,w)); G[v].push_back(Node(u,w));}int k,m;void init(){ for(int i=0;i<maxn;i++) G[i].clear(); mul.clear();}void dij(int st){ priority_queue<pii,vector<pii>,greater<pii> >q; for(int i=0;i<maxn;i++) dis[i]=INF; dis[st]=0; q.push(make_pair(0,st)); while(!q.empty()){ pii u=q.top(); //cout<<u.second<<"!!"<<u.first<<endl; q.pop(); for(int i=0;i<G[u.second].size();i++){ ll d=G[u.second][i].w+u.first; int to=G[u.second][i].to; if(d<dis[to]){ dis[to]=d; q.push(make_pair(dis[to],to)); //cout<<d<<"juli"<<endl; // cout<<G[u.second][i].w<<"jjjjl"<<endl; } } }}void a_star(int st){ mul.insert(qNode(0,st)); k--; while(!mul.empty()){ qNode u=*mul.begin(); mul.erase(mul.begin()); if(u.to==m){ if(k) k--; else {cout<<u.w<<endl;return;} } for(int i=0;i<G[u.to].size();i++){ //cout<<G[u.to][i].w+u.w<<endl; int to=G[u.to][i].to; mul.insert(qNode(u.w+G[u.to][i].w,to)); } //cout<<mul.size()<<"@@@"<<endl; }}/*void a_sta(int st){ priority_queue<qNode>q; q.push(qNode(0,st)); k--; while(!q.empty()){ qNode u=q.top(); q.pop(); if(u.to==m){ if(k)k--; else {printf("%lld\n",u.w);return;} } for(int i=0;i<G[u.to].size();i++){ ll d=G[u.to][i].w+u.w; int to=G[u.to][i].to; q.push(qNode(d,to)); } }}*/int main(){ int t,a,b,n; ll c; scanf("%d",&t); while(t--){ init(); scanf("%d%d",&m,&n); for(int i=0;i<n;i++){ scanf("%d%d%lld",&a,&b,&c); add(a,b,c); } dij(m); k=2; //for(int i=1;i<=m;i++) //cout<<i<<" "<<dis[i]<<endl; a_star(1); } return 0;}
次短路板子(dij逼格高,试着求了一下第三短哈哈)
#include <bits/stdc++.h>using namespace std;/* 次短路的做法, ① 次短路模板,维护两个值。 ② 两次最短路。 ③ A*算法*/const int maxn=1e5+5;const long long INF=1e14;typedef long long ll;struct Node{ int to,val; Node(){}; Node(int _a,int _b){to=_a,val=_b;};};vector<Node>G[maxn];ll dis[maxn];ll dis2[maxn];ll dis3[maxn];void add(int a,int b,ll w){ G[a].push_back(Node(b,w)); G[b].push_back(Node(a,w));}void dij(int st){ for(int i=0;i<maxn;i++){ dis[i]=INF; dis2[i]=INF; //初始化 dis3[i]=INF; } priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >q; dis[st]=0; q.push(make_pair(0,st));//入开头元素 while(!q.empty()){ pair<ll,int>u=q.top(); //cout<<u.first<<endl; q.pop(); if(dis2[u.second]<u.first) continue; for(int i=0;i<G[u.second].size();i++){ ll d=G[u.second][i].val+u.first; int to=G[u.second][i].to; if(d<dis[to]){ swap(d,dis[to]);//最短的。 q.push(make_pair(dis[to],to)); } if(dis[to]<d&&dis2[to]>d){ swap(d,dis2[to]); q.push(make_pair(dis2[to],to)); } /*if(dis3[to]>d&&dis2[to]<d&&dis[to]<d){ dis3[to]=d; q.push(make_pair(dis3[to],to)); }*/ } }}void init(){ for(int i=0;i<maxn;i++) G[i].clear();}int main(){ int t,m,n,a,b; ll c; scanf("%d",&t); while(t--){ scanf("%d%d",&m,&n); init(); for(int i=0;i<n;i++){ scanf("%d%d%lld",&a,&b,&c); add(a,b,c); } //puts("!!!!"); dij(m); /*for(int i=1;i<=m;i++) cout<<dis[i]<<" "<<dis2[i]<<endl;*/ printf("%lld\n",dis2[1]); } return 0;}
暴力枚举最短路,大佬的代码,,,先贴了。。
我第一个思路也是这样,但是想的是,维护最短路径,然后每个节点枚举,,而不是这样全图暴力枚举,,只能说大佬。
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <iostream> using namespace std; typedef long long int ll; const int R = 100000+5; const int INF = 0x3f3f3f3f; int n,m; struct Node { int v; int w; int next; }edge[R*2]; int head[R]; ll dist1[R]; ll dist2[R]; bool vis[R]; int num; void init() { num = 0; memset(head,-1,sizeof(head)); for(int i = 1; i <= n; i++) dist1[i] = dist2[i] = 1e16; } void add_edge(int u,int v,int w) { edge[num].v = v; edge[num].w = w; edge[num].next = head[u]; head[u] = num++; } void SPFA(int u,ll *dist) { int i,v,w; queue<int> Q; memset(vis,false,sizeof(vis)); dist[u] = 0; vis[u] = true; Q.push(u); while(!Q.empty()) { u = Q.front(); Q.pop(); vis[u] = false; for(i=head[u];i!=-1;i=edge[i].next) { v = edge[i].v; w = edge[i].w; if(dist[v] > dist[u] + w) { dist[v] = dist[u] + w; if(!vis[v]) { vis[v] = true; Q.push(v); } } } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int i,j,u,v,w;; init(); for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); add_edge(u,v,w); add_edge(v,u,w); } SPFA(1,dist1); SPFA(n,dist2); int flag = 0; ll ans = 1e16; for(i=1;i<=n;i++) { for(j=head[i];j!=-1;j=edge[j].next) { v = edge[j].v; w = edge[j].w; //cout<<i<<v<<endl; ll tem = dist1[i] + dist2[v] + w; //cout<<tem<<endl; if(tem > dist1[n] && tem < ans) { ans = tem; } } } printf("%I64d\n",ans); } return 0; }
阅读全文
0 0
- hdu6181-启发式搜索A*|次短路模板|最短路枚举-Two Paths
- hdu6181 Two Paths 次短路模板
- HDU6181 Two Paths【次短路】
- HDU6181-Two Paths【A*算法or次短路】
- hdu6181 Two Paths(次短路)
- 第k最短路A*启发式搜索
- hdu 6181 Two Paths -最短路条数+次短路
- HDU6181 Two Paths(次短路,路径记录,spfa,2017 HDU多校联赛 第10场)
- 【hdu6181】Two Paths(次短路----每条边经过不止一次)
- 求最短路即次短路模板,一条边可以重复走的HDU6181
- hdu6181次短路
- hdu6181 How Many Paths Are There(次短路条数[模板])
- hdu Two Paths 次短路模板 (可往回走)
- HDU 6181 Two Paths【次短路】【模板题】
- 2017 Multi-University Training Contest 10 1011 Two Paths HDU 6181 (次短路+最短路数量)
- HDU 6181 Two Paths (次短路)
- hdu 6181 Two Paths (次短路)
- hdu 6181 Two Paths(次短路)
- U盘无显示器无SD卡安装树莓派3
- JS作用域
- 微信小程序制作
- C++STL中,map/multimap,set/multiset 和vector的排序
- 利用java的socket发送一个类
- hdu6181-启发式搜索A*|次短路模板|最短路枚举-Two Paths
- 如何获取sha1值
- Java Maven项目中读取JSON文件报空指针异常以及解决方案
- Chrome谷歌浏览器调试JavaScript
- 关于Python模块安装在另外的路径方法
- Maven工程出现红色感叹号运行不成功的解决思路
- 多校9 Numbers HDU
- jmeter之HTTP取样器、Webserivce采样器、Debug Sampler、Cookie、header、授权、jdbc连接、用户自定义属性和变量
- Android滑动卡TabLayout+ViewPager布局捕获不到返回键Back事件解决办法