【模板】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 &lt; (const node x) const{
        return x.data &lt; data;
    }
} hp;
priority_queue&lt;node&gt; 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(" &gt; %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] &gt; 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",&amp;n,&amp;m);
    for(int i = 1;i &lt;= m;++i) {
        int a, b, w;
        scanf("%d %d %d",&amp;a,&amp;b,&amp;w);
        adline(a,b,w);
    }
    scanf("%d %d",&amp;start,&amp;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;
}

@bikuhiku

posted @ 2022-02-20 08:11  bikuhiku  阅读(16)  评论(0编辑  收藏  举报