目录
1.租用游艇
2.邮递员送信
3.【模板】单源最短路径(标准版)
1.租用游艇
P1359 租用游艇 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
输入数据:
3 5 15 7
因为这道题数据不大,所有我们直接使用Floyd 算法。
这道题大家可能没看懂怎么存图,其实就是第x行的第y个元素,就是从x站到y站的租金,所以是一个半矩阵输入。
下面是完整AC代码:
#include<bits/stdc++.h>
#define inf 1234567890
using namespace std;
int a[201][201];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]=inf;//初始化 for(int i=1;i<n;i++)for(int j=i+1;j<=n;j++){int x;cin>>x;a[i][j]=x;//邻边矩阵存图 }for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)//式子套用 a[i][j]=min(a[i][j],a[i][k]+a[k][j]);cout<<a[1][n]<<endl;return 0;
}
2.邮递员送信
P1629 邮递员送信 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
输入数据:
5 10 2 3 5 1 5 5 3 5 6 1 2 8 1 3 8 5 3 4 4 1 8 4 5 3 3 5 6 5 4 2
这道题需要建立一个返回的图,因为这是有向图,所以1到其他节点和其他节点到1的最短路径不一定是相同的。
使用Dijkstra 算法,我们可以给dis的数组开成两倍大小,这样可以将反图也建在同一个图上,也可以重新建图,但是这样前面的方法方便一些。
下面是完整AC代码:
#include<bits/stdc++.h>
#define M 500010
#define inf 1234567890
using namespace std;
struct edge{int u,v,w,next;
}e[M];
struct node{int w,now;bool operator<(const node &k)const{return w>k.w;//堆优化,小的元素放在堆顶,大根堆 }
};
int head[M],re=0,n,m,s,v[M],dis[M];
priority_queue<node>q;
void add(int u,int v,int w)//链式前向星存图
{e[++re].u=u;e[re].v=v;e[re].w=w;e[re].next=head[u];head[u]=re;
}
void dijkstra(int s)
{for(int i=1;i<=n*2;i++) dis[i]=inf;//将点设置为无穷大 dis[s]=0;//起点设置为0 node p;p.w=0,p.now=s;q.push(p);while(!q.empty()){node k=q.top();q.pop();int u=k.now;if(v[u]) continue;//如果遍历过,直接跳过循环 v[u]=1;for(int i=head[u];i;i=e[i].next){//下一个点 int v=e[i].v;if(dis[v]>dis[u]+e[i].w)//更新最小权重 {dis[v]=dis[u]+e[i].w;q.push((node){dis[v],v});} }}
}
int main()
{cin>>n>>m;for(int i=0;i<m;i++){int u,v,w;cin>>u>>v>>w;//建边 add(u,v,w);add(v+n,u+n,w);//建返回的图 }dijkstra(1);//求出1到其他点的最短路径 int ans=0;for(int i=1;i<=n;i++){ans+=dis[i];}dijkstra(1+n);//求出其他点到1的最短的路径 for(int i=1+n;i<=n*2;i++){ans+=dis[i];}cout<<ans<<endl;return 0;
}
3.【模板】单源最短路径(标准版)
P4779 【模板】单源最短路径(标准版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
输入数据:
4 6 1 1 2 2 2 3 2 2 4 1 1 3 5 3 4 3 1 4 4
既然是模板题目,这里就直接出Dijkstra 算法来解决。
下面是AC完整代码:
#include<bits/stdc++.h>
#define M 500010
#define inf 1234567890
using namespace std;
struct edge{int u,v,w,next;
}e[M];
struct node{int w,now;bool operator<(const node &k)const{return w>k.w;//堆优化,小的元素放在堆顶,大根堆 }
};
int head[M],re=0,n,m,s,v[M],dis[M];
priority_queue<node>q;
void add(int u,int v,int w)//链式前向星存图
{e[++re].u=u;e[re].v=v;e[re].w=w;e[re].next=head[u];head[u]=re;
}
void dijkstra()
{for(int i=1;i<=n;i++) dis[i]=inf;//将点设置为无穷大 dis[s]=0;//起点设置为0 node p;p.w=0,p.now=s;q.push(p);while(!q.empty()){node k=q.top();q.pop();int u=k.now;if(v[u]) continue;//如果遍历过,直接跳过循环 v[u]=1;for(int i=head[u];i;i=e[i].next){//下一个点 int v=e[i].v;if(dis[v]>dis[u]+e[i].w)//更新最小权重 {dis[v]=dis[u]+e[i].w;q.push((node){dis[v],v});} }}
}
int main()
{cin>>n>>m>>s;for(int i=0;i<m;i++){int u,v,w;cin>>u>>v>>w;//建边 add(u,v,w);}dijkstra();for(int i=1;i<=n;i++){cout<<dis[i]<<" ";}return 0;
}