//单源最短路径 //Dijkstra + 优先队列实现 #include<iostream> #include<queue> #include<cstring> #define INF 1200000000 #define MAXN 205 #define MAXM 20005 using namespace std; typedef pair<int,int> dis_v;//用一个pair类型存放当前结点的距离和结点编号 int T,N,M; int head[MAXN],next[MAXM],V[MAXM],W[MAXM],dis[MAXN]; int m; void addEdge(int u,int v,int w) { V[m] = v; W[m] = w; next[m] = head[u]; head[u] = m++; } void buildGraph() { int u,v,w; m = 0; memset(head,-1,sizeof(head)); scanf("%d%d",&N,&M); while(M--) { scanf("%d%d%d",&u,&v,&w); addEdge(u,v,w); addEdge(v,u,w); } } int Dijkstra(int st,int ed)//Dijkstra + 优先队列 { for(int i = 1;i <= N;++i) dis[i] = i == st ? 0 : INF; priority_queue<dis_v> q; q.push(make_pair(dis[st],st)); while(!q.empty()) { dis_v x = q.top(); q.pop(); int u = x.second; if(x.first != dis[u]) continue; //x.first为入队前dis[u]的距离,如果队列中的dis[u]和当前的dis[u]不同,证明u这个结点被处理过,而dijkstra算法每个节点只会被处理一次,所以跳过 for(int e = head[u];e != -1;e = next[e]) if(dis[u] + W[e] < dis[V[e]]) { dis[V[e]] = dis[u] + W[e]; q.push(make_pair(dis[V[e]],V[e])); } } if(dis[ed] == INF) return -1;//不可达 else return dis[ed]; } int main() { scanf("%d",&T); while(T--) { buildGraph(); printf("%d/n",Dijkstra(1,N)); } return 0; }