题目大意是,给定n个点,以及和它们之间的权.求一点能够到达所有各点的最短距离
Sample Input
3 2 2 4 3 5 2 1 2 3 6 2 1 2 2 2 5 3 4 4 2 8 5 3 1 5 8 4 1 6 4 10 2 7 5 2 0 2 2 5 1 5 0Sample Output
很明显,该题考察的就是图论里的dijkstra算法.它的思想是:首先引进一个辅助向量d[i]表示当前所找到的从起点 v到每个终点的最短路径的长度.它的初态为:若从v到vi有狐,则d[i]为弧上的权.否则d[i]为inifity.显然有3 2 3 10
d[j]=min{d[i] | vi属于顶点集}
但是如何来求次短的路径呢?我们知道,如果s是已经求的的最短路径的集合,则一定有:下一条最短路径或者是弧(v,x),或者是中间只经过s的顶点而最后到达顶点x的路径.所以
d[j]=min{d[j]+arcs[j][k]}
有了算法,那么写代码变的比较容易了.代码如下:
#include<stdio.h>
typedef struct item
{
int a[101][101];
int vexsnum,arcnum;
}graph;
graph netGraph;
void shortPath_DIJ(int v0,int *vex,int *cst)
{
int v,d[101],flag[101],i,w,c=0,min;
for(v=0;v<netGraph.vexsnum;v++)
{
d[v]=netGraph.a[v0][v];
flag[v]=0;}
d[v0]=100;
flag[v0]=1;
for(i=1;i<netGraph.vexsnum;i++)
{
min=100;
for(w=0;w<netGraph.vexsnum;w++)
{
if(flag[w]==0&&d[w]<min)
{
v=w;
min=d[w];
}
}
flag[v]=1;
for(w=0;w<netGraph.vexsnum;w++)
{
if(flag[w]==0&&(min+netGraph.a[v][w])<d[w])
{
d[w]=min+netGraph.a[v][w];
}
}
}
min=0;
for(w=0;w<netGraph.vexsnum;w++)
{
if(min<d[w]&&w!=v0)
{
min=d[w];
c=w;
}
}
*vex=v0+1;
*cst=d[c];
}
void initial()
{
int i,j;
for(i=0;i<101;i++)
for(j=0;j<101;j++)
{
netGraph.a[i][j]=100;
}
}
main()
{
int n,i,j,c,v,w,min=10000,temp,cost,min_w,f=0;
while(1)
{
scanf("%d",&n);
if(n==0)break;
min=10000;
min_w=10000;
initial();
netGraph.vexsnum=n;
f=0;
while(n--)
{
scanf("%d",&c);
for(i=0;i<c;i++)
{
scanf("%d%d",&v,&w);
netGraph.a[f][v-1]=w;
}
f++;
}
for(i=0;i<netGraph.vexsnum;i++)
{
shortPath_DIJ(i,&temp,&cost);
if(cost<min_w)
{
min=temp;
min_w=cost;
}
}
if(min_w==100)
{
printf("disjoint/n");
}
else
printf("%d %d/n",min,min_w);}
}
pku 1125
最新推荐文章于 2024-07-15 22:10:26 发布