额,大一暑假写的Dijkstra 队列优化版本,还是比较干净的,翻出来存起来以后备用。
#define inf 9999
#define INF 0x3f3f3f3f
#define loop(x,y,z) for(x=y;x<z;x++)
//下标自1始
int n,m,s,g; //s 为起点 g 为终点
int book[inf],dis[inf]; //book为标记,一个点作为中转点只能走一次
//dis 为起点到此点距离
int father[inf]; //记录路径:每一个点来自于上一个节点的编号
struct Node //存储边
{
int to,w;
Node(int i,int j)
{
to=i;w=j;
}
bool operator< (const Node& i)const
{
return w>i.w;
}
};
vector<Node>edge[inf]; //edge 来存储每一个邻接边
priority_queue<Node>q; //优先队列用来取元素
void init()
{
int i;
memset(book,0,sizeof book);
loop(i,1,n+1)edge[i].clear();
while(!q.empty())q.pop();
loop(i,1,n+1)
dis[i]=INF;
dis[s]=0;
}
void Dijkstra()
{
int i,j,k;
q.push(Node(s,0)); //压入起点
while(!q.empty())
{
Node t=q.top();
q.pop();
int u=t.to;
if(book[u])continue; //取出距离起点最小点(Dijkstra思想),取过就吐掉
book[u]=1;
int len=edge[u].size();
loop(i,0,len) //对中转点每一条邻接边 松弛
{
Node& e=edge[u][i];
if(dis[e.to]>dis[u]+e.w)
{
dis[e.to]=dis[u]+e.w;
father[e.to]=u; //松弛成功更新路径
q.push(Node(e.to,dis[e.to])); //压入此点时,压入的是节点号,以及节点到起点的距离 dis
}
}
}
}
int main()
{
int i,j,k;
scanf("%d%d",&m,&n);
s=n;g=1; //起点和终点别忘记修改
init();
while(m--)
{
scanf("%d%d%d",&i,&j,&k);
edge[i].push_back(Node(j,k)); //这个方法即使有重边也不用修改
edge[j].push_back(Node(i,k));
}
Dijkstra();
printf("%d\n",dis[g]);
return 0;
}