这道题目是上次在北大比赛的时候没做出来。
貌似过得人挺多的,大多数人的算法是两次最短路+枚举
我写的时候发现太麻烦了,后来看到有人说一次就可以了。
这道题考你对最短路的理解。无向图加有向。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define inf 100000000
int N,M;
int map[610][610];
int city[610];
int dis1[610];
int used1[610];
void dij()
{
int i,j,min1,k1;
dis1[1]=0;
//used1[1]=1;
for(i=1;i<N;i++)
{
min1=inf;
for(j=1;j<=N;j++)
{
if(!used1[j]&&min1>dis1[j])
{
k1=j;
min1=dis1[j];
}
}
if(k1==2)break;
used1[k1]=1;
for(j=1;j<=N;j++)
{
if(!used1[j]&&dis1[j]>dis1[k1]+map[k1][j])
{
dis1[j]=dis1[k1]+map[k1][j];
}
}
}
if(dis1[2]<map[1][1])printf("%d/n",dis1[2]); else printf("-1/n");
}
int main()
{
int a,b,d,i,j;
while(scanf("%d",&N),N)
{
memset(map,0x1f,sizeof(map));//初始化一个很大的值
memset(used1,0,sizeof(used1));
memset(dis1,0x1f,sizeof(dis1));
scanf("%d",&M);
for(i=0;i<M;i++)
{
scanf("%d%d%d",&a,&b,&d);
map[a][b]=d;
map[b][a]=d;
}
for(i=1;i<=N;i++)
scanf("%d",&city[i]);
for(i=1;i<N;i++)
{
for(j=i+1;j<=N;j++)
{
if(city[i]==city[j])
continue;
else if(city[i]==1&&city[j]==2)//如果不在一个集合里,单向
map[j][i]=map[1][1];
else if(city[i]==2&&city[1]==1)//同上
map[i][j]=map[1][1];
}
}
dij();
}
return 0;
}
本文探讨了一种解决复杂图论问题的高效算法策略,通过对比和优化传统方法,提出了一种简化版的两次最短路算法,旨在减少实现难度并提升效率。文章详细介绍了算法的实现步骤,并通过实例分析了其在特定场景下的应用效果。
226

被折叠的 条评论
为什么被折叠?



