一看题目给的图,再看看数据,大致就知道是最短路的题目了。
题目本身不难,关键是在于理解数据的含义。
每组数据先输入19组边信息,依次代表从第几个顶点出发有哪些边与之直接相连。
要注意的是图是无向图,所以在更改邻接矩阵时根据无向图的对称性来处理数据
要注意到题目要求的格式控制,是整个输入连通性的信息加上查找的输入算做一组数据,而不是只是查找最短路径时的输入为一组数据。悲剧的在这里WR一次。。。
这个题按理来说用弗洛伊德算法就完事了。。我在这里用的是迪杰斯特拉算法。。。其实时间复杂度是差不多的。弗洛伊德不就是n个迪杰斯特拉嘛?
要注意的是,迪杰斯特拉是来依次求出小的权值,所以邻接矩阵在初始化是全部为无穷大!。。。一开始没有注意全部是0结果肯定是悲剧了。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXNODE 25
#define MAXCOST 9999
using namespace std;
int main()
{
void InputCost(int Cost[][MAXNODE]);
void Dijkstra(int Cost[][MAXNODE],int f,int Distance[],int e);
int Cost[MAXNODE][MAXNODE];
int cnt;
int kkk = 0; /*kkk为格式控制中的数据编号*/
int n,k;
int i,f,e,Distance[MAXNODE];
while(cin>>n) /*格式控制*/ /*题目已说明总共19组数据,先在input函数外输入一组用于方便格式控制*/
{
memset(Cost,0x3f,sizeof(Cost));
while(n--)
{
cin>>k;
Cost[1][k] = 1;
Cost[k][1] = 1;
}
InputCost(Cost);
cin>>cnt; /*输入查找的信息 */
++kkk;
printf("Test Set #%d\n",kkk);
while(cnt--)
{
cin>>f>>e;
Dijkstra(Cost,f,Distance,e);
}
putchar(10);
}
return 0;
}
void InputCost(int Cost[][MAXNODE]) /*数据输入,用邻接矩阵来存储图的信息*/
{
int n,k;
for(int i = 2 ; i <= 19 ; i++)
{
scanf("%d",&n);
for(int j = 0 ; j < n ; j++)
{
scanf("%d",&k);
Cost[i][k] = 1;
Cost[k][i] = 1;
}
}
}
void Dijkstra(int Cost[][MAXNODE],int f,int Distance[],int e)/*f为出发的结点,e为要查找的从f出发到e的顶点*/
{
int s[MAXNODE];
int mindis,dis;
int i,j,u;
for(i=1;i<=20;i++) /*对S数组初始化*/
{
Distance[i]=Cost[f][i];
s[i]=0;
}
s[f]=1; /*标记v0.*/
for(i=1;i<=20;i++)
{
mindis=MAXCOST;
for(j=1;j<=20;j++)
{
if(s[j]==0 && Distance[j]<mindis) /*每一次循环比较得到最短值。*/
{
u=j;
mindis=Distance[j];
}
}
s[u]=1; /*标记u.*/
for(j=1;j<=20;j++)
{
if(s[j]==0)
{
dis=Distance[u]+Cost[u][j];
Distance[j]=(Distance[j]<dis)?Distance[j]: dis; /*修改从初始结点到其他顶点的最短距离。*/
}
}
}
printf("%d to %d: %d\n",f,e,Distance[e]);
}