之前一直不会用邻接表存图,但有的题目必须要用邻接表存,所以就学习了一下。
感觉用vector实现邻接表还是很方便的,虽然效率上有些损失。
而且没想到的是有时候SPFA居然要比DIjkstra更快一些。
Dijkstra (vector实现邻接表)
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <queue>
using namespace std;
typedef long long LL;
const int INF = 1e8;
const int N = 1000 + 10;
struct Edge
{
int v,w;
Edge(int v,int w):v(v),w(w){}
};
vector<Edge> G[N];
int dist[N];
bool vis[N];
int n,m;
void init()
{
for(int i=0;i<N;i++) G[i].clear();
}
void Dijkstra(int s)
{
priority_queue<pair<int,int> > Q;
for(int i=0;i<n;i++)
dist[i]=INF;
memset(vis,0,sizeof(vis));
Q.push(make_pair(0, s));
dist[s]=0;
while(!Q.empty())
{
int u=Q.top().second;
Q.pop();
if(vis[u]) continue ;
vis[u]=1;
for(int i=0;i<G[u].size();i++)
{
Edge& e=G[u][i];
if(dist[u]+e.w<dist[e.v])
{
dist[e.v]=dist[u]+e.w;
Q.push(make_pair(-dist[e.v],e.v)); //默认大的元素优先级高,所以要取最小就加负号
}
}
}
}
int main()
{
int x,y,z;
while(~scanf("%d%d",&n,&m)&&m+n)
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
x--,y--;
G[x].push_back(Edge(y,z));
G[y].push_back(Edge(x,z));
}
Dijkstra(0);
printf("%d\n",dist[n-1]);
}
return 0;
}
SPFA(vector实现邻接表)
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <queue>
using namespace std;
typedef long long LL;
const int INF = 1e8;
const int N = 1000 + 10;
struct Edge
{
int v,w;
Edge(int v,int w):v(v),w(w){}
};
vector<Edge> G[N];
int dist[N];
bool vis[N];
int n,m;
void init()
{
for(int i=0;i<N;i++) G[i].clear();
}
void spfa(int s)
{
queue<int> Q;
for(int i=0;i<n;i++)
dist[i]=INF,vis[i]=0;
Q.push(s);
dist[s]=0;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
vis[u]=0;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i].v;
if(dist[u]+G[u][i].w<dist[v])
{
dist[v]=dist[u]+G[u][i].w;
if(!vis[v])
{
vis[v]=1;
Q.push(v);
}
}
}
}
}
int main()
{
int x,y,z;
while(~scanf("%d%d",&n,&m)&&m+n)
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
x--,y--;
G[x].push_back(Edge(y,z));
G[y].push_back(Edge(x,z));
}
spfa(0);
printf("%d\n",dist[n-1]);
}
return 0;
}