1.给出结点数量,给出遍历结点数量
2.给出遍历结点顺序
3.给出结点之间的距离
4.求解一个路径,保证路径上面有2给出的结点顺序
OK
现在我们来求解这个问题
其实就是
1.读取结点数量
2.用一个数组储存遍历顺序
3.用一个二维数组储存当前两个结点之间的顺序
每个结点互相连通
最多100个结点(有点友好啊)
所以。我们只需要求解两点之间的最短路径即可。
用什么方法呢?
刚刚学了SPFA算法,感觉可以直接把这道题解决掉了。
外层循环,遍历所有结点
内层用我们的SPFA
1.初始化headl,tail
2.把起点入队
3.开始循环,
队首元素出队,找出和这个当前相连的所有点,然后比较长短
4.如果加和小于已经记录的值
5.那么直接更改,当前点入队,然后继续就可以了
大错特错的感觉真奇妙
看来我只空有SPFA的模板,而没学到人家的思路啊!!!
这道题的二维数组只用来记录数据,我咋在人家的基础之上进行删改呢?
spfa算法就是一个不断向着最短路径进行记录的过程,
问题:
1.队列开太短了,虽然每个题目只有100个结点,但是队列的head会根据bfs一直向后移
,所以一定要开得足够大
2.还是关于初始化的问题,我们需要常备着这个min数组,并且除了[i,i]其它都设置为最大值
不要动储存距离的数组
具体什么原理,我还要学
3.无了
放代码:
#include<stdio.h>
int maze[105][105]={0},n,m,ord[10005]={0},line[100005]={0},tag[105]={0},head=1,tail=0,danger=0,min[105][105]={0};
const int inf=90000000;
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&ord[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&maze[i][j]);//从i到j
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
min[i][j]=inf;
}
}
for(int i=1;i<=n;i++)
{
min[i][i]=0;
head=1,tail=0;
tail++;
line[tail]=i;
tag[i]=1;
int start=i;
while(1)
{
if(head>tail)
{
break;
}
int st=line[head];
head++;
tag[st]=0;
for(int j=1;j<=n;j++)
{
if(min[start][j]>min[start][st]+maze[st][j])
{
min[start][j]=min[start][st]+maze[st][j];
if(tag[j]==0)
{
tail++;
line[tail]=j;
tag[j]=1;
}
}
}
}
}
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=n;j++)
// {
// printf("%d ",min[i][j]);
// }
// printf("\n");
// }
for(int i=2;i<=m;i++)
{
danger=danger+min[ord[i-1]][ord[i]];
}
printf("%d",danger);
return 0;
}