Problem B 最短路径
Accepted: 17 Total Submit: 51
Time Limit: 1000ms Memony Limit: 32768KB
Description
?有一个无向加权图,节点的序号从1开始。请你找出度最大的两个点,然后求这两个点之间的最短路径值。
Input
输入有若干个案例,每个案例的第1行有2个整数m,n,m是节点数,n是边数,接着有n行,每行有三个数s,t,v表示从节点s到t的权值是v。
Ouput
输出最短路径。
Sample Input
4 5
1 2 1
2 3 2
1 3 5
1 4 3
4 3 1
Sample Output
3
Hint
Source
zmh
代码:
#include"iostream"
#include <vector>
using namespace std;
int const INF = 0x3fffffff;
int n,m;
int mp[100][100];
int cnt[100],dis[100],path[100],vis[100];
// cnt计算度数
// dis记录距离
// path记录结点
// vis永久标号
void init(){
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(cnt));
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++)
mp[i][j] = INF;
}
for(int i = 0;i <= n;i++){
dis[i] = 99999,path[i] = -1;
}
}
int main(){
while(~scanf("%d %d",&n,&m)){
init();
for(int i = 0;i < m;i++){
int x,y,l;
scanf("%d %d %d",&x,&y,&l);
cnt[x]++;cnt[y]++;//算出度数
mp[x][y] = l,mp[y][x] = l;
}
int mx = 0;
int p1,p2;
// 两个for循环 得到度数最大的两个点
for(int i = 1;i <= n;i++){
if(mx < cnt[i]){
mx = cnt[i],p1 = i;
}
}
mx = 0;
cnt[p1] = 0;
for(int i = 1;i <= n;i++){
if(mx < cnt[i]){
mx = cnt[i],p2 = i;
}
}
bool isFind = false;
int x = p1;
vis[p1] = vis[0] = true;
dis[p1] = 0;
while(!isFind){
for(int i = 1;i <= n;i++){//迪杰斯特拉 每次算一行
if(dis[i] > dis[x] + mp[x][i] && !vis[i] && mp[x][i] != 0){
path[i] = x;
dis[i] = dis[x] + mp[x][i];
}
}
int max = 9999;
x = -1;
for(int i = 1;i <= n;i++){//查找最小的点
if(dis[i] < max && !vis[i]){
max = dis[i],x = i;
}
}
if(x == -1)//找不到说明所有的点都获得永久标号
isFind = true;
else
vis[x] = 1;//设置永久标号
}
printf("%d\n",dis[p2]);
}
return 0;
}