uva 10740 Not the Best
题目大意:求第K短路。
解题思路:A*算法。这题数据量比较小,也可以暴力。
A*算法
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 105;
const int INF = 0x3f3f3f3f;
int n, m;
int s, t, K;
int h[N];
bool vis[N];
struct Node {
int to, dis;
};
int gra[N][N], gra2[N][N];
bool operator < (const Node& a, const Node& b) {
return (a.dis + h[a.to] > b.dis + h[b.to]);
}
void init() {
memset(vis, 0, sizeof(vis));
for(int i = 0; i <= n + 1; i++) h[i] = INF;
h[t] = 0;
for(int i = 1; i <= n; i++) {
int x, m = INF;
for(int j = 1; j <= n; j++) {
if(!vis[j] && m > h[j]) {
m = h[j];
x = j;
}
}
vis[x] = true;
for (int j = 1; j <= n; j++) {
if (!vis[j] && gra2[x][j] + h[x] < h[j]) {
h[j] = gra2[x][j] + h[x];
}
}
}
}
int Astar() {
priority_queue<Node> Q;
init();
if (s == t) K++;
if (h[s] == INF) return -1;
int ans = -1, count = 0;
Node p;
p.to = s;
p.dis = 0;
Q.push(p);
while(!Q.empty()) {
p = Q.top(); Q.pop();
if (p.to == t) count++;
if (count == K) {
ans = p.dis;
break;
}
for (int i = 1; i <= n; i++) {
if (gra[p.to][i] != INF) {
Q.push((Node){i, p.dis + gra[p.to][i]});
}
}
}
return ans;
}
void input() {
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
gra[i][j] = INF;
gra2[i][j] = INF;
}
}
scanf("%d %d %d", &s, &t, &K);
int u, v, d;
for (int i = 0; i < m; i++) {
scanf("%d %d %d", &u, &v, &d);
gra[u][v] = min(gra[u][v], d);
gra2[v][u] = min(gra2[v][u], d);
}
}
int main() {
while (scanf("%d %d", &n, &m) == 2) {
if (n == 0 && m == 0) break;
input();
printf("%d\n", Astar());
}
return 0;
}
暴力
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<stack>
#include<iostream>
#include<queue>
using namespace std;
const int N = 105;
int n, m;
int s, t, k;
struct Edge{
int to, dis;
};
vector<Edge> G[N];
int vis[N];
int BFS(){
int ans = -1;
priority_queue<pair<int, int> > q;
memset(vis, 0, sizeof vis);
q.push(make_pair(0, s));
while(!q.empty()){
pair<int, int> p = q.top();
q.pop();
int dist = -p.first;
int pos = p.second;
if(vis[pos] > k) continue;
vis[pos]++;
if(pos == t && vis[pos] == k){
ans = dist;
break;
}
for(int i = 0;i < G[pos].size();i++){
int to = G[pos][i].to;
int dis = G[pos][i].dis;
q.push(make_pair(-(dis + dist), to));
}
}
return ans;
}
int main(){
while(scanf("%d%d", &n, &m)){
if(n == 0 && m == 0) break;
scanf("%d%d%d", &s, &t, &k);
for(int i = 0; i <= n; i++) G[i].clear();
for (int i = 0; i < m; i++) {
int u, v, d;
scanf("%d%d%d", &u, &v, &d);
G[u].push_back((Edge){v, d});
}
printf("%d\n", BFS());
}
return 0;
}