pat 1003

Dijkstra算法求最短路径

方法一: dijstra + DFS

View Code
  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 const int INF = 10000000 ;
  5 int map[505][505];
  6 int dist[505];
  7 int teamNum[505];
  8 int visit[505];
  9 int N , M, C1, C2;
 10 int pathNum, maxTeamNum;
 11 void initApp()
 12 {
 13     int temp, m, n, i, j; 
 14     memset(visit, 0, sizeof(int)*505);
 15     for( i =0; i< N ;i++)
 16         for( j = 0; j< N; j++)
 17             if(i != j)
 18                 map[i][j] = map[j][i] = INF;
 19 
 20     //init the team number           
 21     for(i = 0; i< N; i++)
 22     {
 23         scanf("%d", &temp);
 24         teamNum[i] = temp;
 25     }
 26 
 27     //init the map
 28     for(m = 0; m < M; m++)
 29     {
 30         scanf("%d %d %d", &i, &j, &temp);
 31         map[i][j] = map[j][i] = temp;  
 32     }
 33 }
 34 void Dijkstra()
 35 {
 36     int i,j;
 37     for(i = 0; i < N; i++)
 38         dist[i] = map[C1][i];
 39     visit[C1] = 1;
 40 
 41     int min, minValue, value;
 42     for(i = 1; i < N; i++)
 43     {
 44         min = -1; minValue = INF;
 45 
 46         //find the next Node
 47         for(j = 0; j< N ;j++){
 48 
 49             if(visit[j] == 0 && dist[j] < minValue)
 50             {
 51                 minValue  = dist[j];
 52                 min = j;
 53             }
 54         }
 55         //no next node or has find the target node
 56         if(min == -1|| min == C2)
 57             break;
 58 
 59         //mark the node        
 60         visit[min] = 1;
 61         //update the distance information 
 62         for(j = 0; j < N; j++)
 63         {
 64             if(visit[j] == 0)
 65             {
 66                 value = dist[min] + map[min][j];
 67                 if(map[min][j] != INF && value < dist[j])
 68                     dist[j] = value;
 69 
 70             }
 71         }
 72 
 73     }    
 74 }
 75 void dfs(int currentId, int currentDis, int currentNum)
 76 {
 77     int i ;
 78     visit[currentId] = 1;
 79     //has find the destination
 80     if(currentId == C2)
 81     {
 82         if(currentDis == dist[C2])
 83         {
 84             pathNum++;
 85             if(currentNum > maxTeamNum)
 86             maxTeamNum = currentNum;
 87         }
 88         return;
 89     }
 90     //current distance has larger than  the length of the shortest path 
 91     if(currentDis > dist[C2])
 92         return ;
 93 
 94     for(i = 0; i< N; i++)
 95     {
 96         if(0 == visit[i] && map[currentId][i]!= INF)
 97         {
 98             dfs(i,currentDis+map[currentId][i],currentNum + teamNum[i] );
 99             visit[i] = 0;
100         }
101     }
102 
103 
104 }
105 int main(int argc, char *argv[])
106 {
107     int flag = 0;
108 
109     while(scanf("%d", &N)!= EOF){
110         
111         pathNum = 0;
112         maxTeamNum = 0;
113         scanf("%d %d %d", &M, &C1, &C2);
114         initApp();
115         Dijkstra();
116         memset(visit, 0 , sizeof(int)*505);
117         dfs(C1, 0, teamNum[C1]);
118     
119         if (flag == 0)
120             flag = 1;
121         else
122             printf("\n");
123 
124         printf("%d %d", pathNum, maxTeamNum);
125     }
126     
127     return 0;
128 }

 方法二: 改动后的dijstra

 方法二增加了两个数组,一个用来记录从源节点到当前节点路径的条数(pathNum[505]),一个用来记录从源节点到达当前节点的最大救援队的数目(maxTeamNum[])

对方法的改动主要再三方面:

1)pathNum的初始化,源节点与当前节点联通时,初始化为一否则为零;maxTeamNum的初始化,源节点与当前节点联通时,初始化为源节点救援队的数目加上当前节点救援

队的数目,否则为零

2)找到下一个最短距离的点p对别的点进行更新时。当p点距离加上p到当前节点距离小于当前节点的最短距离时,更新当前节点的最短距离。并更新maxTeamNum 和 pathNum,pathNum

为p点的值,maxTeamNum 为p点的maxTeamNum+ 当前节点的teamNum

3)找到下一个最短距离的点p对别的点进行更新时。当p点距离加上p到当前节点距离等于于当前节点的最短距离时,更新当前节点的最短距离。并更新maxTeamNum 和 pathNum,当前节点的

pathNum = pathNum  + p点的pathNum; 当p点的maxTeamNum + 当前节点的teamNum 大于当前节点的maxTeamNum 时,更新当前节点的maxTeamNum

View Code
  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 const int INF = 10000000 ;
  5 int map[505][505];
  6 int dist[505];
  7 int teamNum[505],maxTeamNum[505],pathNum[505];
  8 int visit[505];
  9 int N , M, C1, C2;
 10 void initApp()
 11 {
 12     int temp, m, n, i, j; 
 13 
 14     memset(visit, 0, sizeof(int)*505);
 15     memset(maxTeamNum, 0, sizeof(int)*505);
 16     memset(pathNum, 0, sizeof(int)*505);
 17 
 18     for( i =0; i< N ;i++)
 19         for( j = 0; j< N; j++)
 20             if(i != j)
 21                 map[i][j] = map[j][i] = INF;
 22 
 23     //init the team number           
 24     for(i = 0; i< N; i++)
 25     {
 26         scanf("%d", &temp);
 27         teamNum[i] = temp;
 28     }
 29 
 30     //init the map
 31     for(m = 0; m < M; m++)
 32     {
 33         scanf("%d %d %d", &i, &j, &temp);
 34         map[i][j] = map[j][i] = temp;  
 35     }
 36 }
 37 void Dijkstra()
 38 {
 39     
 40     int i,j;
 41     int temp = teamNum[C1] ;
 42     
 43     //初始化距离与 路径条数 以及最大救援数目
 44     for(i = 0; i < N; i++)
 45     {
 46         dist[i] = map[C1][i];
 47         if(dist[i]!= INF)
 48         {
 49             pathNum[i] = 1;
 50             maxTeamNum[i] =teamNum[i]+  temp ;    
 51         }
 52     }
 53 
 54     dist[C1] = 0;
 55     maxTeamNum[C1] = temp;
 56     visit[C1] = 1;
 57 
 58     int min, minValue, value;
 59     for(i = 1; i < N; i++)
 60     {
 61         min = -1; minValue = INF;
 62 
 63         //find the next Node
 64         for(j = 0; j< N ;j++){
 65 
 66             if(visit[j] == 0 && dist[j] < minValue)
 67             {
 68                 minValue  = dist[j];
 69                 min = j;
 70             }
 71         }
 72         //no next node or has find the target node
 73         if(min == -1|| min == C2)
 74             break;
 75 
 76         //mark the node        
 77         visit[min] = 1;
 78         //update the distance information 
 79         for(j = 0; j < N; j++)
 80         {
 81             if(visit[j] == 0)
 82             {
 83                 value = dist[min] + map[min][j];
 84                 if(map[min][j] != INF && value < dist[j])
 85                 {
 86                     dist[j] = value;
 87                     maxTeamNum[j] = teamNum[j] + maxTeamNum[min];
 88                     pathNum[j] = pathNum[min] ;
 89                 }
 90                 else if(map[min][j] != INF && value == dist[j])
 91                 {
 92                     pathNum[j] += pathNum[min];
 93                     if(maxTeamNum[j] < teamNum[j] + maxTeamNum[min])
 94                         maxTeamNum[j] = teamNum[j] + maxTeamNum[min];
 95                 }
 96 
 97             }
 98         }
 99 
100     }    
101 }
102 int main(int argc, char *argv[])
103 {
104     int flag = 0;
105 
106     while(scanf("%d", &N)!= EOF){
107         
108         scanf("%d %d %d", &M, &C1, &C2);
109         initApp();
110         Dijkstra();
111         memset(visit, 0 , sizeof(int)*505);
112 
113         if (flag == 0)
114             flag = 1;
115         else
116             printf("\n");
117 
118         printf("%d %d", pathNum[C2], maxTeamNum[C2]);
119     }
120     
121     return 0;
122 }

 

转载于:https://www.cnblogs.com/graph/archive/2013/03/24/2979437.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值