题目大意就是求最短路,从n到1的最短路。就用来熟悉一下spfa的写法。
一开始贡献了好几次wa,结果发现是因为n,m写反了。。。。
没有什么拐弯的地方,来熟悉spfa直接附上代码:
//邻接矩阵
#include <stack>
#include <queue>
#include <math.h>
#include <cstdio>
#include <vector>
#include <cstring>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
int n, m;
int x, y, z;
int s, e;
bool vis[2005];
int dis[2005];
int a[2005][2005];
int b[2005][2005];
int q[2005];
void spfa( int ss ) {
for( int i = 0; i <= n; i++ ) {
dis[i] = 0x3f3f3f3f;
vis[i] = false;
}
memset(q,0,sizeof(q));
int head = 0, tail = 1;
q[1] = ss;//队列的初始状态,s为起点
dis[ss] = 0;
vis[ss] = true;
while( head < tail ) {//队列不空
head++;
int t = q[head];//取队首元素
vis[t] = false;//释放结点,一定要释放掉,因为这节点有可能下次用来松弛其它节点
for(int i=1;i<=b[t][0];i++){
if(dis[b[t][i]] > dis[t] + a[t][b[t][i]] ){
dis[b[t][i]] = dis[t] + a[t][b[t][i]];//修改最短路
if(vis[b[t][i]]==false){//扩展结点入队
tail++;
q[tail] = b[t][i];
vis[b[t][i]] = true;
}
}
}
}
}
int main(){
while(~scanf("%d%d",&m,&n)){//n结点数;m边数
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for( int i = 1; i <= m; i++ ) {
cin>>x>>y>>z;//x,y一条边的两个结点;z这条边的权值
if(a[x][y]!=0 && a[x][y]<=z )continue;//如果两顶点间有多条边,保留最小的一条
b[x][0]++; b[x][b[x][0]]=y; a[x][y]=z;// b[x,0]以x为一个结点的边的条数
b[y][0]++; b[y][b[y][0]]=x; a[y][x]=z; //无向图
}
spfa(n);
cout<<dis[1]<<endl;
}
return 0;
}