题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1003
参考他人代码。
这种Dijstra的实现,与之前的文章提到的Dijstra的实现不同(http://blog.csdn.net/staibin/article/details/20702925)。之前提到的是直接初始化起点,遍历n-1个节点。现在这种实现是遍历n个节点,所以过程上有些差异。
#include <stdio.h>
#define SIZE 500+5
#define INF 1<<30
int n, m, s, e;
int map[SIZE][SIZE];
bool mark[SIZE];
int dis[SIZE]; // 必备
int team[SIZE];
int maxteam[SIZE];
int pathcount[SIZE];// 题目需求
void dij()
{
// 1. 寻找最近点
// 2. 未找到或为终点,返回
// 3. 把改点加入,处理与改点相连的点
// 初始化
pathcount[s] = 1;
dis[s] = 0;
maxteam[s] = team[s];
int i, j;
for(i=0; i<n; i++)
{
int p, min = INF;
for(j=0; j<n; j++)
{
if(mark[j] == false && dis[j] < min)
{
p=j;
min=dis[j];
}
}// 寻找未被访问且距离最小的节点
if(p == e || min == INF)
{
return ;
}// 到终点,或者没有所连的点
mark[p] = true;
for(j=0; j<n; j++)
{
if(mark[j] == false)
{
int discost = dis[p]+map[p][j];// 计算未访问节点距起点的距离
if(discost < dis[j])
{
dis[j] = discost;
pathcount[j] = pathcount[p];
maxteam[j] = maxteam[p]+team[j];
}
else if(discost == dis[j])//以前有点可到达节点i
{
// pathcount[j]++;
// 这样是错的,因为到p的路径可能不止一条
pathcount[j] += pathcount[p];
maxteam[j] = maxteam[j] > maxteam[p]+team[j] ? maxteam[j] : maxteam[p]+team[j];
}// (a) new path
else
{
// a longer path, doing nothing
}
}
}
}// 遍历n个节点
return ;
}
void Init()
{
int i;
for(i=0; i<n; i++)
{
mark[i] = false;
dis[i] = INF;
team[i] = 0;
pathcount[i] = 0;
maxteam[i] = 0;
for(int j=0; j<n; j++)
{
map[i][j] = INF;
}
}
return ;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt", "r", stdin);
#endif
scanf("%d%d%d%d", &n, &m, &s, &e);
Init();
int i;
for(i=0; i<n; i++)
{
scanf("%d", &team[i]);
}
for(i=0; i<m; i++)
{
int c1, c2, l;
scanf("%d%d%d", &c1, &c2, &l);
map[c1][c2] = map[c2][c1] = l;
}
dij();
printf("%d %d\n", pathcount[e], maxteam[e]);
return 0;
}