任何最短路的本质都是状态的最短路。其中涉及状态的定义以及状态的转移。
当然你也可以用图论对状态建模,然后再跑普通的Dijkstra。
代码
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 5000;
const int inf = 0x3f3f3f3f;
struct Edge
{
int from,to,dist,id;
};
struct HeapNode
{
int d,u;
bool operator < (const HeapNode& rhs) const
{
return d>rhs.d;
}
};
struct Dijkstra
{
int n,m;
vector<Edge>edges;
vector<int>G[maxn];
int d[maxn],done[maxn],p[maxn];
void init(int n)
{
this->n=n;
edges.clear();
rep(i,0,n-1) G[i].clear();
}
void add(int u,int v,int dist,int id)
{
edges.push_back((Edge){u,v,dist,id});
m=edges.size();
G[u].push_back(m-1);
}
void dijkstra(int s)
{
rep(i,0,n-1)
{
d[i]=inf;
done[i]=0;
}
d[s]=0;
priority_queue<HeapNode>Q;
Q.push((HeapNode){0,s});
while(!Q.empty())
{
HeapNode x=Q.top();Q.pop();
int u=x.u;
if(done[u]) continue;
done[u]=1;
for(unsigned int i=0;i<G[u].size();i++)
{
Edge& e=edges[G[u][i]];
if(d[e.to]>d[e.from]+e.dist)
{
d[e.to]=d[e.from]+e.dist;
p[e.to]=G[u][i];
Q.push((HeapNode){d[e.to],e.to});
}
}
}
}
void debug()
{
puts("debug");
for(unsigned int i=0;i<edges.size();i++)
{
Edge& e=edges[i];
printf("%d %d %d\n",e.from,e.to,e.dist);
}
puts("debug");
}
};
int NT,NI;
int nt[22][12],ni[22][12];
int ntn[22],nin[22];
int pri[22];
Dijkstra DIJ;
int kase;
map<int,int>ID;
int N;
vector<int>G[500];
void print(int a,int b,int c,int s,int t)
{
printf("Case %d, Trip %d: Cost = %d\n",a,b,c);
stack<int>S;
while(s!=t)
{
Edge& e=DIJ.edges[DIJ.p[t]];
S.push(e.id);
t=e.from;
}
printf(" Tickets used:");
while(!S.empty())
{
printf(" %d",S.top()+1);
S.pop();
}
puts("");
}
int main()
{
int tp;
while(scanf("%d",&NT)==1&&NT)
{
N=0;
++kase;
ID.clear();
rep(i,0,NT-1)
{
scanf("%d %d",pri+i,ntn+i);
rep(j,0,ntn[i]-1)
{
scanf("%d",&tp);
if(!ID.count(tp)) ID[tp]=N++;
nt[i][j]=ID[tp];
}
}
scanf("%d",&NI);
rep(i,0,NI-1)
{
scanf("%d",nin+i);
rep(j,0,nin[i]-1)
{
scanf("%d",&tp);
ni[i][j]=ID[tp];
}
}
rep(T,0,NI-1)
{
rep(i,0,N-1) G[i].clear();
rep(i,0,NT-1) G[nt[i][0]].push_back(i);
DIJ.init((nin[T]+1)*N);
rep(i,0,nin[T]-1) rep(j,0,N-1) rep(u,0,(int)G[j].size()-1)
{
int k=i;
rep(v,0,ntn[G[j][u]]-1)
{
if(k>=nin[T]) break;
if(ni[T][k]==nt[G[j][u]][v]) k++;
DIJ.add(i*N+j,k*N+nt[G[j][u]][v],pri[G[j][u]],G[j][u]);
//printf("%d %d %d %d %d\n",i,j,k,nt[G[j][u]][v],pri[G[j][u]]);
//printf("%d %d %d\n",i*nin[T]+j,k*nin[T]+nt[G[j][u]][v],pri[G[j][u]]);
}
}
//DIJ.debug();
DIJ.dijkstra(ni[T][0]);
print(kase,T+1,DIJ.d[nin[T]*N+ni[T][nin[T]-1]],ni[T][0],nin[T]*N+ni[T][nin[T]-1]);
}
}
return 0;
}