hnu 11532 最短路

题目大意:在一个无向图中求一个点到另外两个点的距离之和的最小值。

设源点为S,另外两个点为A、B。

我们可以先这样想:假如S到A、B两个点的最短路径没有交叉,那么结果就是dist[A]+dist[B];其实这个值也是最大值。如果有交叉的情况又是什么样的呢?假设交叉点是C,C到A、B的最短距离是dist1[A]、dist1[B]。那么结果很显然就是 dist[C]+dist1[A]+dist1[B];我们枚举所有的C点,求取最小的dist[C]+dist1[A]+dist1[B],不就OK了吗。

然而再想想时间复杂度吧,以上做法可能会达到O(n^3)的复杂度。试着做了一下,果然超时。

其实我们仔细想一想就知道,我们没必要枚举所有的C点,我们只要求出S、A、B到其余个点的最短距离就可以了,正好和刚在所说的是相反的过程,刚才我们求的是其余所有点到S、A、B的最短距离,而现在呢,则是三个点到其余各点的最短距离(想一想为什么),这样我们只求三次最短路径,降低了时间复杂度。应该可以过了吧,修改了一下代码提交了,结果WA ,又修改了一下果然AC了。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define MAX 100000000
struct node
{
int i,w,next;
};
node vert[20001];
queue <int> Q;
int visit[5010],head[5010],N;
int dist1[5010],dist2[5010],dist[5010];
int add(int s,int t,int w)//构建临接表
{
vert[N].i=t;
vert[N].w=w;
vert[N].next=head[s];
return N++;
}
int Dij(int s,int n,int * dis)
{
int i,j,k,t;
int min;
memset(visit,0,sizeof(visit));

for(i=1;i<=n;i++) dis[i]=MAX;

for(j=head[s];j;j=vert[j].next)
dis[vert[j].i]=vert[j].w;
visit[s]=1;
for(i=1;i<n;i++)
{
min=MAX;
for(j=1;j<=n;j++)
if(!visit[j] && min > dis[j])
{
min=dis[j]; k=j;
}
if(min>=MAX) return 0;
visit[k]=1;
for(j=head[k];j;j=vert[j].next)
{
t=vert[j].i;
if(!visit[t] && dis[t] > dis[k]+vert[j].w)
dis[t]=dis[k]+vert[j].w;
}
}
return 0;
}
int work(int start,int city1,int city2,int n)
{
int i,k,min;
min=MAX;
for(i=1;i<=n;i++)
{
k=dist[i]+dist1[i]+dist2[i];
if(k < min) min=k;
}
return min;
}
int main()
{
int i,m,n,s,t,w,res,start,city1,city2,count=0;
while(scanf("%d %d",&n,&m)!=EOF)
{
N=1;
memset(head,0,sizeof(head));
scanf("%d %d %d",&start,&city1,&city2);
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&s,&t,&w);
head[s]=add(s,t,w);
head[t]=add(t,s,w);
}
Dij(start,n,dist);
if(dist[city1]==MAX || dist[city2]==MAX)
{
printf("Scenario #%d\nCan not reach!\n\n",++count);
continue;
}
dist[start]=0;
Dij(city1,n,dist1);
dist1[city1]=0;

Dij(city2,n,dist2);
dist2[city2]=0;

res=work(start,city1,city2,n);
printf("Scenario #%d\n%d\n\n",++count,res);
}
return 0;
}



posted @ 2012-03-12 08:32  书山有路,学海无涯  阅读(219)  评论(0编辑  收藏  举报