题意很简单,就是要求第k短路。
看网上好多人都是用dfs+二分过的,我果断作死写了个dijstra+A*。
但最坑的是这道题竟然标程都PE,估计sgu数据坑...
代码正确性应该还是有的,还是贴贴吧。
<pre name="code" class="cpp">#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 105, INF = 1e9;
int n = 0, m = 0, k = 0, s = 0, e = 0;
int mtx[MAXN][MAXN] = {0};
struct node{int x, g, h, pd[4];};
int dis[MAXN] = {0};
bool used[MAXN] = {0};
int ans = 0, time[MAXN] = {0};
bool operator < (const node &A, const node &B)
{
if((A.g+A.h) == (B.g+B.h)) return A.g > B.g;
else return (A.g+A.h) > (B.g+B.h);
}
void dijstra()
{
for(int i = 1; i <= n; ++i)
dis[i] = INF;
dis[e] = 0;
int cur = e;
for(int i = 1; i <= n; ++i)
{
used[cur] = true;
for(int j = 1; j <= n; ++j)
if(!used[j] && dis[j] > dis[cur]+mtx[cur][j])
dis[j] = dis[cur]+mtx[cur][j];
int minv = INF, minf = 0;
for(int j = 1; j <= n; ++j)
if(!used[j])
if(minv > dis[j])
{
minv = dis[j];
minf = j;
}
cur = minf;
}
}
void A_star()
{
priority_queue<node> q;
node tmp = {s, 0, dis[s], {0}};
tmp.pd[0] += 1<<(s-1);
q.push(tmp);
while(!q.empty())
{
node T = q.top();
q.pop();
time[T.x]++;
if(time[T.x] >= k)
{
if(T.x == e)
{
ans = T.g+T.h;
printf("%d", ans);
return ;
}
if(time[T.x] > k)
continue;
}
for(int i = 1; i <= n; ++i)
{
if(mtx[T.x][i])
{
tmp = T;//二进制是为了判断不能走重复的点。
if(i <= 30)
{
if(T.pd[0]&(1<<(i-1)))
continue;
else tmp.pd[0] += 1<<(i-1);
}
else if(i > 30 && i <= 60)
{
if(T.pd[1]&(1<<(i-31)))
continue;
else tmp.pd[1] += 1<<(i-31);
}
else if(i > 60 && i <= 90)
{
if(T.pd[2]&(1<<(i-61)))
continue;
else tmp.pd[2] += 1<<(i-61);
}
else
{
if(T.pd[3]&(1<<(i-91)))
continue;
else tmp.pd[3] += 1<<(i-91);
}
tmp.x = i;
tmp.g = T.g+mtx[T.x][i];
tmp.h = dis[i];
q.push(tmp);
}
}
}
}
int path[MAXN] = {0}, top = 0;
bool flag = false;
void dfs(int cur, int d)
{
if(d > ans || flag) return ;
path[++top] = cur;
used[cur] = true;
if(cur == e && d == ans)
{
printf(" %d\n", top);
if(top >= 1)
printf("%d", path[1]);
for(int i = 2; i <= top; ++i)
printf(" %d", path[i]);
flag = true;
return ;
}
for(int i = 1; i <= n; ++i)
if(!used[i] && mtx[cur][i])
dfs(i, d+mtx[cur][i]);
path[top--] = 0;
used[cur] = false;
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
if(i != j) mtx[i][j] = INF;
for(int i = 1; i <= m; ++i)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
mtx[x][y] = mtx[y][x] = z;
}
scanf("%d%d", &s, &e);
if(s == e) k++;
dijstra();
A_star();
memset(used, false, sizeof(used));
dfs(s, 0);
return 0;
}