【模板】dijsktra
#include <stdio.h>
#include <queue>
#include <string.h>
const int V = 131072;
const int E = 524288;
struct EDGE {
int t, next;
int w;
} edge[E];
int edge_tot, head[V];
void add_edge(int f,int t,int w) {
edge[++edge_tot].next = head[f];
edge[edge_tot].t = t;
edge[edge_tot].w = w;
head[f] = edge_tot;
}
struct NODE {
int id, val;
NODE () {}
NODE (const int &__u,const int &__length) {id = __u, val = __length;}
bool friend operator < (const NODE &_x,const NODE &_y) {
return _x.val > _y.val;
}
};
int n, m;
std :: priority_queue<NODE> q;
int dis[V];
bool vis[V];
void dijkstra(int start) {
q.push(NODE{start,0});
memset(vis,false,(n+1)*sizeof(bool));
memset(dis,0x3f,(n+1)*sizeof(int));
dis[start] = 0;
while(!q.empty()) {
int u = q.top().id;
int del = q.top().val;
q.pop();
if(!vis[u]) {
vis[u] = true;
for(int i = head[u];i;i = edge[i].next) {
int v = edge[i].t;
if(dis[v] > del+edge[i].w) {
dis[v] = del+edge[i].w;
q.push(NODE{v,dis[v]});
}
}
}
}
}
int begin, end;
signed main() {
scanf("%d %d",&n,&m);
for(int i = 1, a, b, c;i <= m;++i) {
scanf("%d %d %d",&a,&b,&c);
add_edge(a,b,c);
}
scanf("%d",&begin);
dijkstra(begin);
for(int i = 1;i <= n;++i)
printf("%lld ",dis[i]);
}
\(2022.07.29\):重修,差点连dijkstra都不会打了。
#include <bits/stdc++.h>;
using namespace std;
//@cnblogs bikuhiku
const int z = 1024;
int dis[z], head[z], in[z], cnt, ans = 0x7f7f7f, n, m;
int pre[z], start, end;
bool visit[z];
struct node{
int id, data;
bool operator < (const node x) const{
return x.data < data;
}
} hp;
priority_queue<node> q;
struct edge{
int f, t, w;
int next;
} line[z*4];
void adline(int f,int t,int w) {
line[++cnt].f = f;
line[cnt].t = t;
line[cnt].w = w;
line[cnt].next = head[f];
head[f] = cnt;
return;
}
void print(int r) {
if(!pre[r]) {
printf("%d",r);
return;
}
print(pre[r]);
printf(" > %d",r);
}
void dijsktra(int f) {
hp.id = f;
hp.data = 0;
q.push(hp);
memset(dis,50,sizeof(dis));
memset(visit,false,sizeof(visit));
dis[f] = 0;
while(!q.empty()) {
int x = q.top().id;
int y = q.top().data;
q.pop();
if(!visit[x]) {
visit[x] = true;
for(int i = head[x];i;i = line[i].next) {
hp.id = line[i].t;
if(dis[hp.id] > y+line[i].w) {
dis[hp.id] = y+line[i].w;
hp.data = dis[hp.id];
q.push(hp);
pre[hp.id] = x;
}
}
}
}
return;
}
int main() {
scanf("%d %d",&n,&m);
for(int i = 1;i <= m;++i) {
int a, b, w;
scanf("%d %d %d",&a,&b,&w);
adline(a,b,w);
}
scanf("%d %d",&start,&end);
dijsktra(start);
printf("dis = %d\n",dis[end]);
print(end);
return 0;
}
例子
\(\text{luogu P3008 [USACO11JAN]Roads and Planes G}\)
很好的题,一边拓扑一边跑dijkstra
#include <stdio.h>
#include <ctype.h>
#include <queue>
#include <set>
#include <string.h>
char _tc;
signed _sg;
template<typename Tec>
void get_int(Tec &_aim) {
_aim = 0, _sg = 1, _tc = getchar();
for(;!isdigit(_tc);_tc = getchar())
if(_tc == '-') _sg = -1;
for(;isdigit(_tc);_tc = getchar())
_aim = (_aim<<1)+(_aim<<3)+(_tc^48);
_aim *= _sg;
}
template<typename Tec,typename ...Args>
void get_int(Tec &_aim,Args &...args) {
get_int(_aim);
get_int(args...);
}
const int N = 32768;
const int E = 131072+32768;
struct EDGE {
int t, next;
int w;
} edge[E];
int edge_tot, head[N];
void add_edge(int f,int t,int w) {
edge[++edge_tot].next = head[f];
edge[edge_tot].t = t;
edge[edge_tot].w = w;
head[f] = edge_tot;
}
struct NODE {
int id;
long long val;
bool friend operator < (const NODE &_x,const NODE &_y) {
return _x.val > _y.val;
}
};
std :: priority_queue<NODE> p;
std :: queue<int> q;
bool vis[N];
long long dis[N];
int degree[N];
int belong[N], block_cnt;
int n, r, l, s;
void dijkstra(int block_id) {
for(int i = 1;i <= n;++i)
if(belong[i] == block_id)
p.push(NODE{i,dis[i]});
while(!p.empty()) {
int u = p.top().id;
long long del = p.top().val;
p.pop();
if(!vis[u]) {
vis[u] = true;
for(int i = head[u];i;i = edge[i].next) {
int v = edge[i].t;
if(dis[v] > del+edge[i].w) {
dis[v] = del+edge[i].w;
if(belong[u] == belong[v])
p.push(NODE{v,dis[v]});
}
if(belong[u] != belong[v])
if(!--degree[belong[v]])
q.push(belong[v]);
}
}
}
}
void dfs(int u) {
vis[u] = true;
belong[u] = block_cnt;
for(int i = head[u];i;i = edge[i].next) {
int v = edge[i].t;
if(vis[v])
continue;
dfs(v);
}
}
void top(int start) {
memset(dis,0x3f,(n+1)*sizeof(long long));
for(int i = 1;i <= block_cnt;++i)
if(!degree[i]) q.push(i);
dis[start] = 0;
while(!q.empty()) {
memset(vis,false,(n+1)*sizeof(bool));
int id = q.front();
q.pop();
dijkstra(id);
}
}
signed main() {
get_int(n,r,l,s);
for(int i = 1, a, b, c;i <= r;++i) {
get_int(a,b,c);
add_edge(a,b,c);
add_edge(b,a,c);
}
for(int i = 1;i <= n;++i)
if(!vis[i]) {
++block_cnt;
dfs(i);
}
for(int i = 1, a, b, c;i <= l;++i) {
get_int(a,b,c);
add_edge(a,b,c);
}
for(int u = 1;u <= n;++u) {
for(int i = head[u];i;i = edge[i].next) {
int v = edge[i].t;
if(belong[u] != belong[v])
++degree[belong[v]];
}
}
top(s);
for(int i = 1;i <= n;++i)
if(dis[i] >= 1000000000)
printf("NO PATH\n");
else
printf("%lld\n",dis[i]);
return 0;
}