zju 1053 FDNY to the Rescue!

   做这道题的时候,自己恰好刚看过dijstra算法。不过感觉有些地方还是不是那么好处理?去网上看了一下,大家好像说这个题很简单,就感觉自己太菜了。下面写下自己做这个题的过程。
   首先,我要解决的是要存储消防站到火点的路径,并且是存储多个消防站到火点的路径,这个该怎么存储呢?此外,我要存储多个消防站到火点所用的时间,这个该怎么存储呢?还有,怎么根据输入消防站的个数不同来输出呢?这些都成为了我的困扰。
   后来看了网上的代码,感觉对我帮助很大。

    一、我用不用存储每个消防站到火点的路线呢?不用!!我只要将到达该点的最短路径的前驱存储就行了,用不着再用什么二维数组来存储消防站到火点的距离。举个例子,消防站标号为7,火点标号为2。我如何知道从消防站到火点的路径呢?就找7的前驱(假设为5),这个点就是消防站到火点的第一步,如果5的前驱不是2继续找5的前驱并继续下去,如果5的前驱是2了,那就结束。因此路径是7->5->2。
    二、消防站到火点的时间怎么存储呢?我设置一个数组d[],d[i]就代表从火点到i的最短时间。
    三、这个算法找到的是火点到各个路口的最短路径,但是我并不全要啊,我要的是那些消防站在的那些路口的数据。如何解决这个问题呢?我设置一个数组station[],对那些消防站在的那些路口进行标记。比如,1号路口有消防站,则将station[1]标记为1,二号路口没有消防站,则将station[2]标记为0。最后根据station[i]是否为1来进行输出。
    四、输出的时候要怎么处理呢?我如何保证对每个消防站都进行了输出呢?此时,我设置一个变量stasum记录消防站的个数,每输出一次,k++,当k!=stasum时,就保证输出结束了。
     这些仅仅是一些方面,有什么问题的欢迎交流。。我是菜鸟。。

 1 #include<iostream>  
 2 using namespace std;  
 3 #define MAXV 20  
 4 #define INF INT_MAX  
 5   
 6 int map[MAXV][MAXV],d[MAXV],parent[MAXV];  //d[i]表示是从火点到i点最短路径的长度 
 7 int n,fire,stasum,station[MAXV];  //parent[i]表示是在最短路径上i的前驱  fire表示的是火点所在的位置 
 8 //staion[i]的值用来标记消防站 
 9 void dijkstra(){  
10     int i,j,v,tmp;  
11     bool vis[MAXV];  
12     memset(parent,-1,sizeof(parent));  
13     memset(vis,false,sizeof(vis));  
14    for(i=1;i<=n;i++) d[i]=INF;  
15     d[fire]=0;  
16   
17     for(i=1;i<=n;i++){   
18         tmp=INF;  
19         for(j=1;j<=n;j++)  //这个过程是找出离火点最近的并且是没有访问过的路口 
20             if(d[j]<tmp && !vis[j]){  
21                 tmp=d[j];  
22                 v=j;  
23             }  
24         vis[v]=true;  
25         for(j=1;j<=n;j++){  
26             if(!vis[j] && map[v][j]!=-1 && d[j]>d[v]+map[v][j]){     //-1不能走  
27                 d[j]=d[v]+map[v][j];  
28                parent[j]=v;        //记录路径  
29             }  
30         }  
31     }  
32 }  
33  
34 void output(){  
35     int j,i,tmp,v;  
36     printf("Org Dest    Time    Path\n");  
37       
38     j=0;  
39     while(j!=stasum){  
40         tmp=INF;  
41         for(i=1;i<=n;i++){                   //每次找最小的时间输出  
42             if(station[i] && d[i]<tmp){  //注意我是要找消防站点输出的啊,必须要求station[i]==1 
43                tmp=d[i];  
44                 v=i;  
45             }  
46         }  
47         station[v]=0;                       //将这个站点设为非消防站点(这点也很重要啊) 
48         printf("%d  %d  %d",v,fire,d[v]);  
49         while(v!=-1){  
50             printf("    %d",v);  
51             v=parent[v];  
52         }  
53         cout<<endl;
54         j++;  
55     }  
56 }  
57   
58 int main(){  
59     int i,j,x;  
60     scanf("%d",&n);  
61     for(i=1;i<=n;i++){  
62         for(j=1;j<=n;j++){  
63             scanf("%d",&map[j][i]);     //边反向存储  
64         }  
65     }  
66     scanf("%d",&fire);  
67     stasum=0;  
68     memset(station,0,sizeof(station)); 
69     while(getchar()!='\n')
70   {
71     cin>>x;
72     station[x]=1; //标记消防站 
73     stasum++;  //计算消防站总数 
74   }
75     dijkstra();  
76     output();  
77     return 0;  
78 }  

 

posted @ 2012-11-17 15:48  简单地快乐  阅读(252)  评论(0编辑  收藏  举报