题目标号:A-1003
这个题目看到的时候,把它简单地理解成求最短路径,于是想到了用dijkstra算法求图的最短路径。但是最后由于自己黔驴技穷,无法统计顶点的权值。只能参考CSDN上一个浙大CS硕士的一篇文章(需要的请移步至 最短路径数 Dijkstra+dfs ,是个漂亮的姐姐O(∩_∩)O~~)。于是这次由单纯的dijkstra算法变成这样:dijkstra + dfs ,而后我又在网上查到一篇文章只用了dfs(需要的童鞋请移步至 PAT 1003. Emergency (25) (求两点间最短路的条数))就搞定了最短路径数目的统计与最大顶点权值和的统计。两个算法都能通过OJ的多个测试点,但是前者所有测试点用了148ms,后者只用了4ms,区别在最后一个测试点。两种C程序均经过自己重新书写,附在题目后面。
题目:
菜鸟代码:
1.开始的使用dijkstra + dfs的:
#include "stdio.h"
#include "stdlib.h"
#define INF 99999999
#define MAXNUM 1000
typedef struct
{
int matrix[MAXNUM][MAXNUM] ;
int m ;
int n ;
}G ;
int distance[MAXNUM];
int teams[MAXNUM], maxTeam = 0 , same = 0 , minDis = INF;
void dijksra(G *g , int v )
{
int visited[MAXNUM] = { 0 } ;
int path[MAXNUM] = {0} ;
int i = 0 , j = 0, u = v ;
visited[v] = -1 ;
for( i = 0 ; i< g->m ; i ++)
{
distance[i] = g->matrix[v][i] ;
}
for( i = 0 ; i< g->m -1; i ++)
{
int j ;
int min = INF ;
for( j =0 ; j < g->m ; j ++ )
{
if( ( visited[j] != -1 ) && ( distance[j] < min) )
{
min = distance[j];
u = j ;
}
}
visited [u] = -1 ;
for( j = 0 ; j < g->m ; j ++)
{
if( ( visited[j] != -1 ) && ( g->matrix[u][j] != INF))
{
if( distance[u] + g->matrix[u][j] < distance[j] )
{
distance[j] = distance[u] + g->matrix[u][j] ;
path [j] = u ;
}
}
}
}
}
int hasvisited[MAXNUM] = {0} ;
// depth first traversal
void dfs(G *g , int v , int c2, int dis , int p)
{
int i;
/*
if( v == c2 )
{
if( dis < minDis )
{
same = 1 ;
maxTeam = p ;
minDis = dis ;
}
else if( dis == minDis )
{
same ++ ;
if(p > maxTeam )maxTeam = p ;
}
return ;
}
*/
if( (v==c2) && (distance[c2] == dis))
{
same ++ ;
if( p > maxTeam ) maxTeam = p ;
}
if( dis> minDis )return;
for( i = 0 ; i< g->m ; i ++)
{
if( (hasvisited[i]!= -1) && ( g->matrix[v][i] != INF) )
{
hasvisited[i] = -1;
dfs(g , i , c2 , dis + g->matrix[v][i] , p+ teams[i]);
hasvisited[i] = 0 ;
}
}
}
int main(void)
{
int m , n , c1 , c2 , dis , currsum , i , j ;
G *g = (G*)(malloc(sizeof(G)));
// m : cities ; n : roads
scanf("%d %d %d %d" , &m , &n , &c1 , &c2);
g->m = m ;
g->n = n ;
for( i = 0 ; i < MAXNUM ;i++ )
{
for( j = 0 ; j < MAXNUM ; j++ )
{
g->matrix[i][j] = INF ;
}
}
for( i = 0 ; i < m ; i++)
{
scanf("%d" , &teams[i]);
}
while( n -- )
{
int a , b , l ;
scanf("%d %d %d" , &a , &b , &l);
g->matrix[a][b] = g->matrix[b][a] = l < g->matrix[b][a] ? l : g->matrix[b][a];
}
dijksra(g , c1 );
hasvisited[c1] = -1 ;
dis = 0 ;
currsum = teams[c1] ;
distance[c1] = 0 ;
dfs(g , c1 , c2, dis , currsum);
printf("%d %d\n" , same , maxTeam);
return 0 ;
}
2.只使用dfs的:
#include "stdio.h"
#include "stdlib.h"
#define INF 99999999
#define MAXNUM 1000
typedef struct
{
int matrix[MAXNUM][MAXNUM] ;
int m ;
int n ;
}G ;
int *distance;
int teams[MAXNUM], maxTeam = 0 , same = 0 , minDis = INF;
void dijksra(G *g , int v )
{
int visited[MAXNUM] = { 0 } ;
int path[MAXNUM] = {0} ;
int i = 0 , j = 0, u = v , dis[MAXNUM];
visited[v] = -1 ;
for( i = 0 ; i< g->m ; i ++)
{
dis[i] = g->matrix[v][i] ;
}
for( i = 0 ; i< g->m -1; i ++)
{
int j ;
int min = INF ;
// Ì°ÐÄ·¨ÌôÑ¡×î½üµÄµã
for( j =0 ; j < g->m ; j ++ )
{
if( ( visited[j] != -1 ) && ( dis[j] < min) )
{
min = dis[j];
u = j ;
}
}
visited [u] = -1 ;
for( j = 0 ; j < g->m ; j ++)
{
if( ( visited[j] != -1 ) && ( g->matrix[u][j] != INF))
{
if( dis[u] + g->matrix[u][j] < dis[j] )
{
dis[j] = dis[u] + g->matrix[u][j] ;
path [j] = u ;
}
}
}
}
distance = dis;
}
int hasvisited[MAXNUM] = {0} ;
// depth first traversal
void dfs(G *g , int v , int c2, int dis , int p)
{
int i;
if( v == c2 )
{
if( dis < minDis )
{
same = 1 ;
maxTeam = p ;
minDis = dis ;
}
else if( dis == minDis )
{
same ++ ;
if(p > maxTeam )maxTeam = p ;
}
return ;
}
if( dis> minDis )return;
for( i = 0 ; i< g->m ; i ++)
{
if( (hasvisited[i]!= -1) && ( g->matrix[v][i] != INF) )
{
hasvisited[i] = -1;
dfs(g , i , c2 , dis + g->matrix[v][i] , p+ teams[i]);
hasvisited[i] = 0 ;
}
}
}
int main(void)
{
int m , n , c1 , c2 , dis , currsum , i , j ;
G *g = (G*)(malloc(sizeof(G)));
// m : cities ; n : roads
scanf("%d %d %d %d" , &m , &n , &c1 , &c2);
g->m = m ;
g->n = n ;
for( i = 0 ; i < MAXNUM ;i++ )
{
for( j = 0 ; j < MAXNUM ; j++ )
{
g->matrix[i][j] = INF ;
}
}
for( i = 0 ; i < m ; i++)
{
scanf("%d" , &teams[i]);
}
while( n -- )
{
int a , b , l ;
scanf("%d %d %d" , &a , &b , &l);
g->matrix[a][b] = g->matrix[b][a] = l < g->matrix[b][a] ? l : g->matrix[b][a];
}
//dijksra(g , c1 );
hasvisited[c1] = -1 ;
dis = 0 ;
currsum = teams[c1] ;
//distance[c1] = 0 ;
dfs(g , c1 , c2, dis , currsum);
printf("%d %d\n" , same , maxTeam);
return 0 ;
}