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] <<' ';
}