第k短路

poj 2449 模板题  A*+spfa

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #define mt(a,b) memset(a,b,sizeof(a))
  6 using namespace std;
  7 const int inf=0x3f3f3f3f;
  8 class AStar { ///A*+spfa求第k短路
  9     typedef int typec;///边权的类型
 10     static const int ME=1e5+10;///边的个数
 11     static const int MV=1e3+10;///点的个数
 12     struct G {
 13         struct E {
 14             int v,next;
 15             typec w;
 16         } e[ME];
 17         int le,head[MV];
 18         void init(int n) {
 19             le=0;
 20             for(int i=0; i<=n; i++) head[i]=-1;
 21         }
 22         void add(int u,int v,typec w) {
 23             e[le].v=v;
 24             e[le].w=w;
 25             e[le].next=head[u];
 26             head[u]=le++;
 27         }
 28     };
 29     class Spfa { ///单源最短路o(k*ME)k~=2
 30         G g;
 31         int n,inque[MV],i,u,v;
 32         typec dist[MV];
 33         bool used[MV];
 34         queue<int> q;
 35     public:
 36         void init(int tn) { ///传入点的个数
 37             n=tn;
 38             g.init(n);
 39         }
 40         void add(int u,int v,typec w) {
 41             g.add(u,v,w);
 42         }
 43         bool solve(int s) { ///传入起点,存在负环返回false
 44             for(i=0; i<=n; i++) {
 45                 dist[i]=inf;
 46                 used[i]=true;
 47                 inque[i]=0;
 48             }
 49             used[s]=false;
 50             dist[s]=0;
 51             inque[s]++;
 52             while(!q.empty()) q.pop();
 53             q.push(s);
 54             while(!q.empty()) {
 55                 u=q.front();
 56                 q.pop();
 57                 used[u]=true;
 58                 for(i=g.head[u]; ~i; i=g.e[i].next) {
 59                     v=g.e[i].v;
 60                     if(dist[v]>dist[u]+g.e[i].w) {
 61                         dist[v]=dist[u]+g.e[i].w;
 62                         if(used[v]) {
 63                             used[v]=false;
 64                             q.push(v);
 65                             inque[v]++;
 66                             if(inque[v]>n) return false;
 67                         }
 68                     }
 69                 }
 70             }
 71             return true;
 72         }
 73         typec getdist(int id) {
 74             return dist[id];
 75         }
 76     } spfa;
 77     struct Q {
 78         int p;
 79         typec g,h;
 80         friend bool operator <(const Q &a,const Q &b) {
 81             return a.g+a.h>b.g+b.h;
 82         }
 83     } now,pre;
 84     priority_queue<Q> q;
 85     int n,cnt[MV];
 86     G g;
 87     typec ans;
 88 public:
 89     void init(int tn) {
 90         n=tn;
 91         g.init(n);
 92         spfa.init(n);
 93     }
 94     void add(int u,int v,typec w) {
 95         g.add(u,v,w);
 96         spfa.add(v,u,w);
 97     }
 98     bool solve(int s,int t,int k) {
 99         if(s==t) k++;
100         spfa.solve(t);
101         while (!q.empty()) q.pop();
102         for(int i=0; i<=n; i++) cnt[i]=0;
103         now.p=s;
104         now.g=0;
105         now.h=0;
106         q.push(now);
107         while(!q.empty()) {
108             pre=q.top();
109             q.pop();
110             int u=pre.p;
111             cnt[u]++;
112             if(cnt[u]==k&&u==t) {
113                 ans=pre.h+pre.g;
114                 return true;
115             }
116             if(cnt[u]>k) continue;
117             for(int i=g.head[u]; ~i; i=g.e[i].next) {
118                 now.h=pre.h+g.e[i].w;
119                 int v=g.e[i].v;
120                 now.g=spfa.getdist(v);
121                 now.p=v;
122                 q.push(now);
123             }
124         }
125         return false;
126     }
127     typec getans() {
128         return ans;
129     }
130 } gg;
131 int main() {
132     int n,m,u,v,w,s,t,k;
133     while(~scanf("%d%d",&n,&m)) {
134         gg.init(n);
135         while(m--) {
136             scanf("%d%d%d",&u,&v,&w);
137             gg.add(u,v,w);
138         }
139         scanf("%d%d%d",&s,&t,&k);
140         if(!gg.solve(s,t,k)) {
141             puts("-1");
142         } else {
143             printf("%d\n",gg.getans());
144         }
145     }
146     return 0;
147 }

时间: 2024-10-11 00:27:03

第k短路的相关文章

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

poj2449:第k短路问题

Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, he told them a story. "Prince Remmarguts lives in his kingdom UDF – United Delta of Freedom. One

图的第k短路

[问题描述] 给你一个有向图,求从1到n的第k短路. [解法] SPFA+A*搜索. 1 A*算法 A*算法在人工智能中是一种典型的启发式搜索算法,启发中的估价是用估价函数表示的: h(n)=f(n)+g(n) 其中f(n)是节点n的估价函数,g(n)表示实际状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价.另外定义h'(n)为n到目标节点最佳路径的实际值.如果h'(n)≥h(n)则如果存在从初始状态走到目标状态的最小代价的解,那么用该估价函数搜索的算法就叫A*

POJ 2499 A*求第K短路

DES就是给你一个图.然后给你起点和终点.问你从起点到终点的第K短路. 第一次接触A*算法. // 大概懂思路了.A*算法需要的估价函数里的两个函数.一个是起点到当前点的消耗. //一个是当前点到目标点的估测消耗.所以需要用Dijstra或者Spfa求出目标点到所有点的最短路. //然后就可以用A*算法来求了. // 确实.学了位运算.链式表. #include<cstdio> #include<iostream> #include<queue> #include<

poj2449 Remmarguts&#39; Date,第K短路

点击打开链接 SPFA  + A* #include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; struct node { int v, dis, f, next; friend bool operator <(node a, node b){ return a.f>b.f; } }; const int INF =

poj 2449 Remmarguts&#39; Date k短路

/*poj 2449 k短路 A* 估价函数是 s到i的距离+i到t的距离 */ #include<cstdio> #include<queue> #include<vector> #define inf 1e7 #define maxn 100010 using namespace std; int n,m,S,T,K,num1,num2,head1[maxn],head2[maxn],dis[maxn]; int q[maxn],hea,tai,f[maxn],cn

POJ 2449Remmarguts&#39; Date K短路模板 A*+SPFA

太水了我不想说了,模板在这里 14312K 313MS 1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int v[100010],v2[100010],c[100010],c2[100010],s,t,k,duin; 7 int n,m,point[1010],next[100010],cnt=0,

POJ 2449(求k短路,A*)

题目:求s到t的第k短路. 思路:网上是清一色的A*算法,所以学习了一下.所谓Astar算法其实就是启发式的bfs.这里设置了一个估价函数h,结合当前位置的最短路和到终点的估计最短路长度来选择下一个要扩展的节点(dijkstra算法对于所有的点的h值可以视为是一样的,所以下一个扩展的节点只与当前的最短路g有关).这个h的值越接近手记最短路越好,但是不能少于实际最短路(否则会错误),假设h值就是实际最短路的值,那么这个Astar算法可以一次找到最短路,相对的,如果h比实际值稍大,那么仍然可以去掉很

【k短路&amp;A*算法】BZOJ1975: [Sdoi2010]魔法猪学院

Description 找出1~k短路的长度. Solution k短路的求解要用到A*算法 A*算法的启发式函数f(n)=g(n)+h(n) g(n)是状态空间中搜索到n所花的实际代价 h(n)是n到结束状态最佳路径的估计代价 关于h(n)的选取,当h(n)<实际代价时,搜索慢但可出解:h(n)=实际代价时,正确率与效率最高:h(n)>实际代价,快但只能得到近似解. 但在k短路问题中,h(n)是可以选到准确值的,就是n到结束节点的最短路,预处理时从结束节点做一次单源最短路即可. 按广搜的方式

再探第k短路

其实这是一个很古老的姿势啦- 只不过今天跟同学讨论A*算法求k短路的时候,同学不信A*算法能被卡掉. 于是我翻了翻课件找出了一种n元环的特殊情况,卡掉了A*算法. A*算法是只有到达终点的时候才能统计答案,这导致可能拓展很多个状态才能得到一个用来更新答案的有效状态. 例如一个n元环,当我们到达终点之后,可能还要拓展n次才能得到下一个状态.于是若求k短路时间复杂度就为O(nk).于是就容易被卡掉. 我们考虑换一种方式来定义一条从起点s到终点t的路径. 构建出以t为终点的最短路树,t是这棵树的根,对