1.p2910
用floyd把到每个点的最短路径算出来,再把每个到每个点加起来
#include <iostream> #include <algorithm> #include<string.h> using namespace std; const int max_n=300; int s[10010]; int a[max_n][max_n]; int main() { int n,m; cin >> n >> m; for(int i=1;i<=m;i++) cin >> s[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin >> a[i][j]; } for(int k=1;k<=n;k++)//中间点 for(int i=1;i<=n;i++)//i到j for(int j=1;j<=n;j++) { a[i][j]=min(a[i][j],a[i][k]+a[k][j]);//两条路选最短 } int ans=0; for(int i=2;i<=m;i++) ans+=a[s[i-1]][s[i]]; cout <<ans; }
2、下午听学长讲dijkstra算法
1、对low进行初始化为最大,代表不能走,vis标记为0代表每个点没用过,再建图
2、每次访问最小点,再对low数组更新一下,每更新一次low数组就对该点标记
3、直到所有点被走过
#include <iostream> #include <string.h> #include<queue> using namespace std; int n,m,s,t; const int max_n=1e7; const int inf=0x7fffffff; int low[max_n],vis[max_n],head[max_n],cnt;//存最短路径,标记,头; //链式前向星 struct Edge { int to,v,next; }edge[max_n]; //优先队列 struct node{ int idx; int v; bool operator<(const node &x) const {return x.v < v;} }; void add(int x,int y,int z) { edge[++cnt].next=head[x]; edge[cnt].to=y; edge[cnt].v=z; head[x]=cnt; } void init()//初始化 { for(int i=1;i<=n;i++) { vis[i]=0; low[i]=inf; } } void dij() { low[s]=0; priority_queue<node> q; q.push({s,0});//起点 while(q.size()) { int idx = q.top().idx; q.pop(); if(vis[idx]) continue;//此点要没被走过 vis[idx]=1; for(int i=head[idx];i;i=edge[i].next) { int a=idx,b=edge[i].to,v=edge[i].v; if(low[b]>low[a]+v) { low[b]=low[a]+v; if(!vis[b])q.push({b,low[b]}); } } } } int main() { cin >> n >> m>>s; for(int i=1;i<=m;i++) { int x,y,z; cin >> x >>y >> z; add(x,y,z);//建图 } init(); dij(); for(int i=1;i<=n;i++) cout << low [i] <<' '; }