题意:有n个城市,m条连接两个城市的道路,每条道路有自己的最大复载量。现在问从城市a到城市b,车上的最大载重能为多少。
思路:dijkstra。在松弛的地方要改一下,即当前点now的最大负载为min(dict[now], edge[now][i]),这很关键。其次输入求城市名称对应的顶点编号要注意下,然后就是赤裸裸的dij了。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 1100;
const int inf = -10000000;//***这是使用dijkstra来解决最大生成树是需要改的地方.1)
int map[maxn][maxn];
int d[maxn];
int s[maxn];
int n, m;
int start,end;//动态制定某一条路径的起点和终点
/**
* dijkstra算法用于有向加权图的最短路径问题
*
* 有一个大神总结的很好(至少我个人比较赞同..):
* 用最小生成树算法来求最小边权和
* 用dijkstra算法将所有的最小值都存起来
*/
int dijkstra(int v) { //选择v作为源节点,利用dijkstra算法计算源节点v到各节点的最短路径
int i;
for (i = 1; i <= n; ++i) { //初始化
s[i] = 0; //s[i] = 0,表示i节点未被访问过
d[i] = map[v][i]; //将d[i]定义为源节点v到节点i的最短距离
}
int j;
for (i = 1; i < n; ++i) {//这里< 或者是 <= 都会AC
int mmin = inf;
int pos;
for (j = 1; j <= n; ++j) {
if (!s[j] && mmin < d[j]) {//***这是使用dijkstra来解决最大生成树是需要改的地方.2)
pos = j;
mmin = d[j];
}
}
s[pos] = 1;
for (j = 1; j <= n; ++j) {
if (!s[j] && (d[j]<min(d[pos],map[pos][j]))) {//***这是使用dijkstra来解决最大生成树是需要改的地方..3)
d[j] = min(d[pos],map[pos][j]);
}
}
}
return d[end]; //返回所要求的源节点到n节点的最短路径
}
//***以上是使用dijkstra来解决最大生成树问题的模板
//***以下是使用当节点不是用数字表示而是用字符串表示的时候的处理方法...
char name[maxn][35];
int sum;
int find_ver(char *str){ // 求城市名str对应的顶点编号,以前没有出现过的话则新建顶点。
int i;
bool new_ver = true;
for(i = 1; i <= sum; i ++)
if(strcmp(str, name[i]) == 0){
new_ver = false;
break;
}
if(new_ver) strcpy(name[++sum], str); // 以前没有出现过。
return i;
}
int main(){
int counter = 1;
while(scanf("%d%d",&n,&m)!=EOF,n||m){
memset(map,0,sizeof(map));
sum = 0;
int i;
char str1[35],str2[35];
int weight;
for(i = 1 ; i <= m ; ++i){
scanf("%s%s%d",str1,str2,&weight);
int u = find_ver(str1);
int v = find_ver(str2);
map[u][v] = map[v][u] = weight;
}
scanf("%s%s",str1,str2);
start = find_ver(str1);
end = find_ver(str2);
printf("Scenario #%d\n",counter++);
printf("%d tons\n\n",dijkstra(start));
}
return 0;
}