[最短路径SPFA] POJ 1847 Tram

Tram
Time Limit: 1000MS		Memory Limit: 30000K
Total Submissions: 14630		Accepted: 5397
Description

Tram network in Zagreb consists of a number of intersections and rails connecting some of them. In every intersection there is a switch pointing to the one of the rails going out of the intersection. When the tram enters the intersection it can leave only in the direction the switch is pointing. If the driver wants to go some other way, he/she has to manually change the switch. 

When a driver has do drive from intersection A to the intersection B he/she tries to choose the route that will minimize the number of times he/she will have to change the switches manually. 

Write a program that will calculate the minimal number of switch changes necessary to travel from intersection A to intersection B. 
Input

The first line of the input contains integers N, A and B, separated by a single blank character, 2 <= N <= 100, 1 <= A, B <= N, N is the number of intersections in the network, and intersections are numbered from 1 to N. 

Each of the following N lines contain a sequence of integers separated by a single blank character. First number in the i-th line, Ki (0 <= Ki <= N-1), represents the number of rails going out of the i-th intersection. Next Ki numbers represents the intersections directly connected to the i-th intersection.Switch in the i-th intersection is initially pointing in the direction of the first intersection listed. 
Output

The first and only line of the output should contain the target minimal number. If there is no route from A to B the line should contain the integer "-1".
Sample Input

3 2 1
2 2 3
2 3 1
2 1 2
Sample Output

0
Source

Croatia OI 2002 Regional - Juniors

原题大意:输入三个数N,A,B;N代表有多少个点,A代表起始点,B代表终点。

              接下来的N行,第i行第一个数T代表在i点的边的个数,接下来读入T个数代表与它相连的点,除了第一个数与i点的路径长为0,其他全为1.

             求最短路径。

解题思路:裸一遍SPFA,FLOYYED或者迪杰斯特拉都可以解决这道题。

              以下是SPFA的解法,已经注释。

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
queue<int> q;
struct mp
  { 
     int len,next,to;
  }map[12010];
int num,frist[12010];
void add(int x,int y,int len)
   {
   	  ++num;
   	  map[num].to=y;map[num].len=len;
   	  map[num].next=frist[x];frist[x]=num;  //用数组模拟链表,存储边
   }
void spfa(int begin,int end)
   {
   	  bool visit[12010];
   	  int x,p,i,dist[12010];
   	  while(!q.empty()) q.pop();
   	  memset(visit,false,sizeof(visit));
   	  for(i=0;i<12010;++i) dist[i]=inf;   //dist[I]代表I点距离begin的距离
   	  q.push(begin);dist[begin]=0;
   	  while(!q.empty())                      
   	    {
   	       x=q.front();visit[x]=false;
   	       for(i=frist[x];i;i=map[i].next)   //枚举与x点相连的每一个边
   	         {
   	            if(dist[x]+map[i].len<dist[map[i].to])
   	               {
   	               	  dist[map[i].to]=dist[x]+map[i].len;
   	               	  if(!visit[map[i].to])
   	               	    {
   	               	    	q.push(map[i].to);
   	               	    	visit[map[i].to]=true;
						}
				   }
			 }
			 q.pop();
		}
		if(dist[end]==inf) printf("-1
");else printf("%d
",dist[end]);
		return;
   }
int main()
  {
  	 int N,A,B,i,n,x,j,cnt,ans;
  	 while(~scanf("%d%d%d",&N,&A,&B))
  	 {
  	 memset(frist,0,sizeof(frist));
  	 num=0;
  	 for(j=1;j<=N;++j)
  	   {
  	   	  scanf("%d",&n);
  	   	  for(i=0;i<n;++i) 
			{
			  scanf("%d",&x);
			  if(i==0) add(j,x,0); else add(j,x,1);  //初始化
		    }
	   }
	   spfa(A,B);
     }
  	 return 0;
  }

  

原文地址:https://www.cnblogs.com/fuermowei-sw/p/6146990.html