题目大意:输入边数和顶点数以及路径对应关系和权值,求小女孩从最后一个结点回到起点的最短路径。
解题思路:很明显的最短路的题,写了好几道基础的写法,这里换成了另外一种vector+邻接表+优先队列的模板写法,算法的核心部分前面几题都给出了详细注释,这里不再赘述,详见code。
题目来源:http://poj.org/problem?id=2387
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 1000+10;
const int INF = 0x3fffffff;
int t,n,m,a,b,w;
struct edge{
int from,to,dist;
};
struct heapnode{ //优先队列结点
int d,u;
bool operator < (const heapnode& rhs) const{
return d>rhs.d;
}
};
vector<edge> edges; //边列表
vector<int> g[MAXN]; //每个结点出发的边编号
bool done[MAXN]; //是否标记
int d[MAXN]; //s到各个点的距离
int p[MAXN]; //最短中的上一条边
void init(int n){
for(int i=0;i<n;i++) g[i].clear(); //清空邻接表
edges.clear(); //清空边表
}
void addedge(int from,int to,int dist){ //增加边
edges.push_back((edge){from,to,dist});
m=edges.size();
g[from].push_back(m-1);
}
void dijkstra(int s){
priority_queue<heapnode> q;
for(int i=0;i<=n;i++) d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
q.push((heapnode){0,s});
while(!q.empty()){
heapnode x= q.top();q.pop();
int u= x.u;
if(done[u]) continue;
done[u]=true;
for(int i=0;i<g[u].size();i++){
edge& e = edges[g[u][i]];
if(d[e.to]>d[u]+e.dist){
d[e.to]=d[u]+e.dist;
p[e.to]=g[u][i];
q.push((heapnode){d[e.to],e.to});
}
}
}
}
int main(){
while(scanf("%d%d",&t,&n)!=EOF){
init(n);
while(t--){
scanf("%d%d%d",&a,&b,&w);
addedge(a,b,w);
addedge(b,a,w);
}
dijkstra(1);
printf("%d\n",d[n]);
}
return 0;
}