1. Dijkstra算法

代码(优先队列+邻接表优化)HDU-2544

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 106;
const int INF = 0x3f3f3f3f;

typedef pair<int, int> p;
vector<p> v[N];
int dis[N];

int n, m;
void dijk(int u)
{
memset(dis, INF, sizeof(dis));
dis[u] = 0;
priority_queue<p, vector<p>, greater<p> > q;
q.push(make_pair(0, u));
while(!q.empty()){
p t = q.top();
q.pop();
if(dis[t.second] != t.first)
continue;
for (int i = 0; i < v[t.second].size(); i++){
if(dis[v[t.second][i].first]>t.first+v[t.second][i].second)
{
dis[v[t.second][i].first]=t.first+v[t.second][i].second;
q.push(make_pair(dis[v[t.second][i].first],v[t.second][i].first));
}
}
}
cout << dis[n] << endl;
}

int main()
{
while(cin >> n >> m){
if(n == 0 && m == 0)
break;
for (int i = 1; i <= n; i++){
v[i].clear();
}
int x, y, w;
while(m--){
scanf("%d%d%d", &x, &y, &w);
v[x].push_back(make_pair(y, w));
v[y].push_back(make_pair(x, w));
}
dijk(1);
}
return 0;
}

上面写法不是人看的。。。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e4 + 10;

int n, m, x, y, val;
int to[N], ne[N], w[N], h[N], idx;
int dis[N];

void add(int a, int b, int val){
to[idx] = b, w[idx] = val, ne[idx] = h[a], h[a] = idx++;
}

struct node{
int u, di;
node(int u, int di):u(u), di(di){}
friend bool operator < (const node& a, const node& b) {
return a.di > b.di;
}
};

void dijk(){
memset(dis, INF, sizeof(dis)), dis[1] = 0; // 初始化
priority_queue<node> q; // 优先小的 di
q.push((node(1, 0))); // 放入 1 号点
while(!q.empty()){
node cnt = q.top();
q.pop();
if(dis[cnt.u] != cnt.di)
continue;
for(int i = h[cnt.u]; ~i; i = ne[i]){ // 更新和 u 相邻的所有边
if(dis[to[i]] > cnt.di + w[i]){ //
dis[to[i]] = cnt.di + w[i];
q.push(node(to[i], dis[to[i]]));
}
}
}
printf("%d\n", dis[n]);
}

int main(){
while(scanf("%d%d", &n, &m)){
if(n == 0 && m == 0)
break;
memset(h, -1, sizeof(h)), idx = 0;
while(m--){
scanf("%d%d%d", &x, &y, &val);
add(x, y, val);
add(y, x, val);
}
dijk();
}
return 0;
}

图的顶点小的情况下,用邻接表存:

int t, v, e, s, k, c;
int dd[M][M];
int kk[N];

struct node{
int u, di;
node(int u, int di):u(u), di(di){}
friend bool operator < (const node& a, const node& b) {
return a.di > b.di;
}
};

int dis[N];

int dijk(int rt){
memset(dis, INF, sizeof(dis)), dis[rt] = 0; // 初始化
priority_queue<node> q; // 优先小的 di
q.push((node(rt, 0))); // 放入 1 号点
while(!q.empty()){
node cnt = q.top();
q.pop();
if(dis[cnt.u] != cnt.di)
continue;
for(int i = 1; i <= v; i++){
if(dis[i] > cnt.di + dd[cnt.u][i]){
dis[i] = cnt.di + dd[cnt.u][i];
q.push(node(i, dis[i]));
}
}
}
int res = 0;
for(int i = 1; i <= v; i++){
res = max(res, dis[i]);
}
return res;
}


int main(){
scanf("%d", &t);
while(t--){
memset(dd, INF, sizeof(dd));
scanf("%d%d%d%d%d", &v, &e, &s, &k, &c);
for(int i = 0; i < k; i++){
scanf("%d", &kk[i]);
}
for(int i = 0, x, y, z; i < e; i++){
scanf("%d%d%d", &x, &y, &z);
dd[x][y] = dd[y][x] = min(dd[x][y], z);
}
int slen = dijk(s);
for (int i = 1; i < k; i++){
dd[kk[i - 1]][kk[i]] = dd[kk[i]][kk[i - 1]] = 0;
}
int ans = dijk(kk[0]);
if(slen > ans * c){
printf("%d\n", ans);
}else{
printf("%d\n", slen);
}
}
return 0;
}