【Step1】【SPFA最短路】poj 1847-Tram

试题传送门

题目大意:

输入数据中,第一行给出n个点,起点和终点。

接下来n行,每行第一个数x,xi为第i个点和几个点有边。接下来x个数,到第一个点代价为0,其余为1。

求从起点到终点的最小代价。

 

这里是我们讲的第一个算法:SPFA(shortest-path-fastest-algorithm,最短路快速算法)

最短路顾名思义,就是求最短的道路,在我们的生活中也很常用。SPFA主要是解决从一个固定的点到其他点的最短路。(又叫做:单源最短路)

具体的可以去看别人的博客,我们简单的讲一讲吧。

 

SPFA类似DP(动态规划)的思想。用数组f[i]表示从st点到达各个点的最小代价。

我们从起点向各个和它相连的点更新。如果新更新的点y能够取到比原来更小的值。那么相应的,从y到其他点的值会更小。

我们用一个队列存储接下来要更新的点。直到怎么都无法找到更优解,我们就停止。

具体代码如下:

while(head!=tail)
	{
		int x=q[head];//队列
		for(int i=first[x];i!=0;i=a[i].next)
		{
			int y=a[i].y;
			if(f[y]>f[x]+a[i].d)
			{
				f[y]=f[x]+a[i].d;
				if(tf[y]==false)
				{
					tf[y]=true;//当然,如果这个点本来就在之后要更新的点之中,我们就不需要再次加入队列。
					q[tail]=y;
					tail++;
					if(tail>n)tail=1;//循环队列,不展开来讲了
				}
			}
		}
		tf[x]=false;//它还有可能加入队列,所以记得还原
		head++;
		if(head>n)head=1;
	}

 

那么这一道题的代码也就呼之欲出了。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 struct qq{
 5     int x,y,d,next;
 6 }a[20005];
 7 int first[105];
 8 int f[105];
 9 bool tf[105];
10 int q[105];
11 int n,st,ed,len=0;
12 void make_l(int x,int y,int d)
13 {
14     len++;
15     a[len].x=x;
16     a[len].y=y;
17     a[len].d=d;
18     a[len].next=first[x];
19     first[x]=len;
20     //printf("%d %d %d\n",a[len].x,a[len].y,a[len].d);
21 }
22 int main()
23 {
24     scanf("%d %d %d",&n,&st,&ed);
25     len=0;
26     memset(first,0,sizeof(first));
27     memset(f,63,sizeof(f));
28     for(int i=1;i<=n;i++)
29     {
30         int xx;
31         scanf("%d",&xx);
32         for(int j=1;j<=xx;j++)
33         {
34             int y;
35             if(j==1)
36             {
37                 scanf("%d",&y);
38                 make_l(i,y,0);
39             }
40             else {
41                 scanf("%d",&y);
42                 make_l(i,y,1);
43             }
44         }
45     }
46     int head=1,tail=2;
47     memset(tf,false,sizeof(tf));tf[st]=true;
48     f[st]=0;q[1]=st;
49     //printf("%d",f[1]);
50     while(head!=tail)
51     {
52         int x=q[head];
53         for(int i=first[x];i!=0;i=a[i].next)
54         {
55             int y=a[i].y;
56             if(f[y]>f[x]+a[i].d)
57             {
58                 f[y]=f[x]+a[i].d;
59                 if(tf[y]==false)
60                 {
61                     tf[y]=true;
62                     q[tail]=y;
63                     tail++;
64                     if(tail>n)tail=1;
65                 }
66             }
67         }
68         tf[x]=false;
69         head++;
70         if(head>n)head=1;
71     }
72     if(f[ed]>=1061109567)printf("-1\n");
73     else
74     printf("%d",f[ed]);
75     return 0;
76 }
我的代码

 

posted @ 2017-11-13 13:21  ZSYZlhy  阅读(112)  评论(0编辑  收藏  举报