题目链接
是一个求最短路的模板题(题目中都写最短路23333)。
一般建图比较方便的是用邻接矩阵的方法,但是对于dijkstra算法来说,其时间复杂度为O()。
我们有一个更好的优化算法:即利用优先队列(小根堆)进行时间上的优化,复杂度可以达到O((m+n)logm)。
(题外话:vector真心真心好用,vector是已经封装了的,又不像链表那么麻烦,最关键的是,大部分在图上的操作用邻接表(vector)比邻接矩阵效率要高很多)
复杂度分析论证:
下面附上这道题的代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#define maxn 10005
using namespace std;
int dis[maxn];
struct Edge
{
int u,v,w;
Edge(int uu,int vv,int ww):u(uu),v(vv),w(ww){}
};
struct Node
{
int id;
int w;//从源点到这个点的最短路径,一直更新给dis[]
bool operator<(const Node &b)
const {w>b.w;}
}mid;
vector<Edge>e[maxn<<1];
priority_queue<Node>pq;
void dijk(int s)
{
pq.push(Node{s,0});
dis[s]=0;
while(!pq.empty())//可以直接拿出最短的那条边
{
mid=pq.top();
pq.pop();
int card=mid.id;
if(mid.w!=dis[card])
continue;
for(int i=0;i<e[card].size();i++)
{
if(dis[e[card][i].v]>dis[card]+e[card][i].w)//一直更新
{
dis[e[card][i].v]=dis[card]+e[card][i].w;
pq.push(Node{e[card][i].v,dis[e[card][i].v]});
}
}
}
}
int main(void)
{
int n,m;
int a,b,c;
while(~scanf("%d%d",&n,&m)&&(n+m))
{
//memset(vis,false,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=n;i++)
e[i].clear();
//
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[b].push_back(Edge(b,a,c));
e[a].push_back(Edge(a,b,c));//建图
}
dijk(1);
printf("%d\n",dis[n]);
}
return 0;
}
呼呼