方法:最短路
解析:
我只是写一个堆优化Dijkstra的模板,毕竟以前没写过。
另外别问我为什么开map那个数组,只是懒得删了而已,所以开就开了。
代码:
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 110
#define M 10010
using namespace std;
typedef long long ll;
int n,m,cnt;
int a[M];
int head[N];
int dis[N];
int map[N][N];
int v[N];
struct node
{
int from,to,val,next;
}edge[M];
void init()
{
memset(head,-1,sizeof(head));
memset(dis,0x3f,sizeof(dis));
cnt=1;
}
void edgeadd(int from,int to,int val)
{
edge[cnt].from=from,edge[cnt].to=to,edge[cnt].val=val;
edge[cnt].next=head[from];
head[from]=cnt++;
}
struct element
{
int v,val;
};
priority_queue <element>q;
bool operator < (element a,element b)
{
if(a.val==b.val)return a.v<b.v;
return a.val>b.val;
}
int dijkstra(int s,int t)
{
memset(dis,0x3f,sizeof(dis));
memset(v,0,sizeof(v));
element fir;
fir.v=s,fir.val=0;
dis[s]=0;
q.push(fir);
while(!q.empty())
{
element u=q.top();
q.pop();
if(v[u.v])continue;
v[u.v]=1;
for(int i=head[u.v];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
if(dis[u.v]+edge[i].val<dis[to])
{
dis[to]=dis[u.v]+edge[i].val;
element pus;
pus.v=to,pus.val=dis[to];
q.push(pus);
}
}
}
return dis[t];
}
int main()
{
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
if(i==j)continue;
edgeadd(i,j,map[i][j]);
}
ll ans=0;
for(int i=2;i<=m;i++)
{
ans+=dijkstra(a[i-1],a[i]);
}
printf("%lld\n",ans);
}