刚复习完floyd,开始复习dijkstra,大二那会学过一波不是很懂,dp做的多了发现真的就简单233,反正我只是一个会裸题的弱鸡
不定时更新dijkstra的模板比如邻接表和堆优化的dijkstra,马上省赛了也不知道会不会出图论,希望出来我能秒ac233.对应的意思模板代码里我都注释了看代码就好。
# include <iostream>
# include <numeric>
# include <algorithm>
# include <functional>
# include <list>
# include <map>
# include <set>
# include <stack>
# include <deque>
# include <queue>
# include <vector>
# include <ctime>
# include <cstdlib>
# include <cmath>
# include <string>
#include <cstring>
#include<cstdio>
using namespace std;
#define ll long long int
const int inf = 0x3f3f3f3f;
const int maxn = 1e2 + 10;
int book[maxn][maxn];
int dis[maxn];
bool flag[maxn];
void fun()
{
for(int i = 0; i < maxn; i++)
{
for(int j = 0; j < maxn; j++)
{
if(i == j)
{
book[i][j] = 0;
}
else
book[i][j] = inf;
}
}
}
int main(int argc, char *argv[])
{
int n, m;
while(scanf("%d%d",&n,&m)!=EOF)
{
fun();
//读入边
for(int i = 1; i <= m; i++)
{
int x, y, len;
scanf("%d%d%d", &x, &y,&len);
if(len < book[x][y])
{
book[x][y] = len;
}
}
//初始化源点的路程,表示源点到各个点的距离这里用1来当源点
for(int i = 1; i<=n; i++)
{
dis[i] = book[1][i];
}
//初始化标记路程
memset(flag, false, sizeof(flag));
//源点标记为1
flag[1] = true;
//dijkstra
//当前点有1个初始化点所以执行n-1次就可以
for(int i = 1; i <= n -1; i++)
{
//首先找到距离源点最近的点
int minn = inf;
int k = -1;
for(int j = 1; j <= n; j++)
{
if(minn > dis[j] && !flag[j])
{
minn = dis[j];
k = j;
}
}
if(k != -1)
{
flag[k] = true;
//表示当前源点到j的距离能不能被源点到k + book[k][j]中转松弛
for(int j = 1; j <= n; j++)
{
if(book[k][j] < inf)
{
if(dis[j] > dis[k] + book[k][j])
{
dis[j] = dis[k] + book[k][j];
}
}
}
}
}
for(int i = 1; i <= n; i++)
{
printf("%d ", dis[i]);
}
printf("\n");
}
return 0;
}
# if 0
测试数据:
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
0 1 8 4 13 17
#endif
邻接表实现的dijkstra
# include <iostream>
# include <numeric>
# include <algorithm>
# include <functional>
# include <list>
# include <map>
# include <set>
# include <stack>
# include <deque>
# include <queue>
# include <vector>
# include <ctime>
# include <cstdlib>
# include <cmath>
# include <string>
# include <cstring>
# include <iomanip>
using namespace std;
# define ll long long int
const int maxn = (7e3 + 5)* 2;
const int inf = 0x3f3f3f3f;
int first[maxn];
int ne[maxn];
int u[maxn], v[maxn], w[maxn], dis[maxn], flag[maxn];
int f[maxn];//记录路径
int n, m, s, t;//s,t是起始点
void fun1()
{
memset(first, -1, sizeof(first));
memset(ne, -1, sizeof(ne));
}
void fun2()
{
memset(f, false, sizeof(f));
memset(dis, inf, sizeof(dis));
memset(flag, false, sizeof(flag));
}
void read()
{
for(int i = 1; i <= m; i++)
{
cin >> u[i] >> v[i] >> w[i];
ne[i] = first[u[i]];
first[u[i]] = i;
}
//双向路劲
for(int i = m + 1; i <= m * 2; i++)
{
u[i] = v[i - m];
v[i] = u[i - m];
w[i] = w[i - m];
ne[i] = first[u[i]];
first[u[i]] = i;
}
}
void dijkstra()
{
fun2();
dis[s] = 0;
for(int i = 1; i <= n; i++)
{
int minn = inf;
int k = -1;
for(int j = 1; j <= n; j++)
{
if(dis[j] < minn && !flag[j])
{
minn = dis[j];
k = j;
}
}
if(minn == inf)
break;
flag[k] = true;
for(int j = first[k]; j != -1; j= ne[j])
{
if(dis[v[j]] > dis[k] + w[j])
{
dis[v[j]] = dis[k] + w[j];
f[v[j]] = k;//存松弛的路径
}
}
}
cout << dis[t] << endl;
return ;
}
void dfs(int x)//打印路径
{
cout << x << endl;
if(f[x] == 0)
return ;
else
{
dfs(f[x]);
if(x == n)
cout << f[x] << endl;
else
cout << f[x] << " ";
}
}
int main(int argc, char *argv[])
{
ios_base::sync_with_stdio(false);
std::cin.tie(false);
while(cin >> n >> m >> s >> t)
{
fun1();
read();
dijkstra();
dfs(n);
}
return 0;
}
//堆优化
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#define in(a) a=read()
#define REP(i,k,n) for(long long i=k;i<=n;i++)
#define MAXN 10010
using namespace std;
typedef pair<long long,long long> P;
inline long long read(){
long long x=0,t=1,c;
while(!isdigit(c=getchar())) if(c=='-') t=-1;
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*t;
}
long long n,m,s;
long long total=0,head[MAXN],nxt[MAXN<<10],to[MAXN<<10],val[MAXN<<10];
long long dis[MAXN],vis[MAXN];
priority_queue <P, vector<P>,greater<P> > Q;//优先队列优化
inline void adl(long long a,long long b,long long c){
total++;
to[total]=b;
val[total]=c;
nxt[total]=head[a];
head[a]=total;
return ;
}
inline void Dijkstra(){
REP(i,1,n) dis[i]=2147483647;
dis[s]=0;
Q.push(P(0,s));
while(!Q.empty()){
long long u=Q.top().second;//取出dis最小的点
Q.pop();//弹出
if(vis[u]) continue;
vis[u]=1;
for(long long e=head[u];e;e=nxt[e])
if(dis[to[e]]>dis[u]+val[e]){
dis[to[e]]=dis[u]+val[e];
Q.push(P(dis[to[e]],to[e]));//插入
}
}
return ;
}
int main(){
in(n),in(m),in(s);
long long a,b,c;
REP(i,1,m) in(a),in(b),in(c),adl(a,b,c);
Dijkstra();
REP(i,1,n) printf("%lld ",dis[i]);
}