24h購物| | PChome| 登入
2013-08-28 07:33:04| 人氣2,584| 回應0 | 上一篇 | 下一篇

[UVA][A*] 1217 - Route Planning

推薦 0 收藏 0 轉貼0 訂閱站台

Superior Island is a very picturesque island and only bicycles are allowed on the island. Therefore, there are many one-way bicycle roads connecting the dierent best photo-shooting spots on the island. To help the visitors plan their trip to the island, the tourism commission wants to designate r different bicycle routes that go through some of the best photo-shooting spots on the island. Given a map of all the bicycle roads on the island and a list of the best photo-shooting spots to be included on each of the three planned routes (non-listed spots must not be included in the route), please write a program to plan each of the r routes so that the distance on each route is minimal. Note that each best photo-shooting spot may only appear at most once on the route.

Input 

There are two parts to the input. The first part of input gives the information of the bicycle roads on the island. The first line contains two integer n and r , n$ le$100 and r$ le$10 , indicating that there are n best photo-shooting spots on the island and there are r routes to be planned. The next n lines (line 2 through line n + 1 ) contains n×n integers (n lines with n integers on each line), where the j -th integer on line i denotes the distance from best photo-shooting spot i - 1 to best photo-shooting spot j ; the distances are all between 0 and 10, where 0 indicates that there is no one-way road going from best photo-shooting spot i - 1 to spot j .

The second part of input has r lines, denoting the r sightseeing routes to be planed. Each line lists the best photo-shooting stops to be included in that route. The integers on each line denote the recommended photo-shooting stops on that particular sightseeing route. The first integer on the line is the starting point of the route and the last integer is the last stop on the route. However, the stops in between can be visited in any order.

Output 

Output r integers on r lines (one integer per line) indicating the distance of each of the r planned routes. If a route is not possible, output `0'.

Sample Input 

6 3
0 1 2 0 1 1
1 0 1 1 1 0
0 2 0 1 3 0
4 3 1 0 0 0
0 0 1 1 0 0
1 0 0 0 0 0
1 3 5
6 3 2 5
6 1 2 3 4 5

Sample Output 

5 
0 
7



每定起點與終點,圖中經過的點任你排序,求總路徑長最小。
n <= 100,因此不太可能狀態壓縮,但是測資中路徑上的點不超過 20,
但為了保險起見,使用 A*,並且將所有狀態點壓成 4 個 int 的 bitmask,
H function 則採用使用剩餘點的單源最短路徑到終點。


#include <stdio.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <queue>
#include <string.h>
using namespace std;
struct E {
int mark[5], used;
int last;
int g, h;//f = g + h
E() {
memset(mark, 0, sizeof(mark));
last = g = h = 0;
}
int GET(int x) {
return mark[x>>5]>>(x&31)&1;
}
void SET(int x) {
mark[(x)>>5] |= 1<<(x&31);
}
bool operator<(const E &a) const {
if(g+h != a.g+a.h)
return g+h > a.g+a.h;
if(g != a.g)
return g < a.g;
if(used != a.used)
return used < a.used;
return memcmp(mark, a.mark, sizeof(mark)) > 0;
}
};
int g[105][105], f[105][105];
int rcnt = 0, route[105];
int h(E tn) {//single shortest path to END node.
queue<int> Q;
static int dist[105], inq[105], i, tnode;
for(i = 0; i < rcnt; i++)
dist[i] = 0xfffffff, inq[i] = 0;
Q.push(tn.last);
dist[tn.last] = 0;
while(!Q.empty()) {
tnode = Q.front(), Q.pop();
inq[tnode] = 0;
for(i = 0; i < rcnt; i++) {
if(f[tnode][i] && tn.GET(i) == 0) {
if(dist[i] > dist[tnode] + f[tnode][i]) {
dist[i] = dist[tnode] + f[tnode][i];
if(inq[i] == 0)
inq[i] = 1, Q.push(i);
}
}
}
}
return dist[rcnt-1] != 0xfffffff ? dist[rcnt-1] : -1;
}
int astar(int route[], int rcnt, int n) {
int i, j, k;
int st = route[0], ed = route[n-1];
for(i = 0; i < rcnt; i++)
for(j = 0; j < rcnt; j++)
f[i][j] = g[route[i]][route[j]];
priority_queue<E, vector<E> > pQ;
E tn;
tn.SET(0);//START node used.
tn.last = 0;
tn.g = 0, tn.h = h(tn);
tn.used = 1;
if(tn.h == -1) return -1;
pQ.push(tn);
while(!pQ.empty()) {
tn = pQ.top(), pQ.pop();
if(tn.used == rcnt) {
return tn.g;
}
//printf("%d ------\n", tn.used);
for(i = 0; i < rcnt; i++) {
if(tn.GET(i) == 0 && f[tn.last][i]) {
if(i == rcnt-1 && tn.used+1 != rcnt)
continue;
E tm = tn;
tm.SET(i), tm.last = i;
tm.g = tn.g + f[tn.last][i];
tm.h = h(tm);
tm.used++;
if(tm.h < 0) continue;
pQ.push(tm);
}
}
}
return -1;
}
int main() {
int n, m;
int i, j, k;
char s[1024];
while(scanf("%d %d", &n, &m) == 2) {
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
scanf("%d", &g[i][j]);
while(getchar() != '\n');
while(m--) {
gets(s);
stringstream sin(s);
rcnt = 0;
while(sin >> route[rcnt])
rcnt++;
int ret = astar(route, rcnt, n);
printf("%d\n", ret < 0 ? 0 : ret);
}
}
return 0;
}

台長: Morris
人氣(2,584) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: UVA |
此分類下一篇:[UVA][IDA*] 11163 - Jaguar King
此分類上一篇:[UVA][bfs] 10923 - Seven Seas

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文