她走的悄無聲息,消失的無影無蹤。
至今我還記得那一段時間,咱們一塊兒旅遊,一塊兒遊遍山水。到了最終的景點,她卻悄無聲息地消失了,只剩我孤身而返。
如今我還記得,那個旅遊區能夠表示爲一張由
個節點 條邊組成無向圖。我故地重遊,卻發現本身只想儘快地結束此次旅遊。我從景區的出發點(即 1 號節點)出發,卻只想找出最短的一條迴路從新回到出發點,而且中途不重複通過任意一條邊。
即:我想找出從出發點到出發點的小環。node
每一個測試點有多組測試數據。
第一行有一個正整數T表示數據組數。
接下來對於每組數據,第一行有兩個正整數n,m分別表明圖的點數和邊數。
接下來有m行,每行三個整數u,v,d表示u,v之間存在一條長度爲d的路徑。
保證不存在重邊,自環。ios
對於每組測試數據,輸出題目中所求的最小環的長度。
無解輸出-1。測試
2 3 3 1 2 1 2 3 1 3 1 1 4 5 1 2 2 2 3 2 3 4 2 1 4 2 1 3 5
3 8
對於100%的數據:
\(n⩽10^4\)
\(m⩽4×10^4\)
本題不卡spfaspa
分三部分來講code
親測spfa和dij都可過
對於隨機數據spfa更快get
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> using namespace std; inline int read(){ int x = 0, w = 1; char ch = getchar(); for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1; for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; return x * w; } const int ss = 100005; struct e{ int to, nxt, w; }edge[ss << 1]; int head[ss << 1], tot; inline void add(register int u, register int v, register int w){ edge[++tot].to = v; edge[tot].nxt = head[u]; edge[tot].w = w; head[u] = tot; } queue<int> q; bool vis[ss]; int dis[ss], point[ss], w[ss], num[ss]; inline void spfa(register int s){ memset(dis, 0x3f, sizeof dis); memset(vis, 0, sizeof vis); dis[s] = 0; q.push(s); while(!q.empty()){ register int u = q.front(); q.pop(); vis[u] = 0; for(register int i = head[u]; i; i = edge[i].nxt){ register int v = edge[i].to; if(dis[v] > dis[u] + edge[i].w){ dis[v] = dis[u] + edge[i].w; if(!vis[v]){ q.push(v); vis[v] = 1; } } } } } struct node{ int to, val; }a[ss]; int cnt; int tmp[ss << 1]; inline int min(register int a, register int b){ return a < b ? a : b; } inline void swap(register int &a, register int &b){ int tmp = b; b = a; a = tmp; } signed main(){ freopen("leave.in", "r", stdin); freopen("leave.out", "w", stdout); register int T = read(); while(T--){ memset(head, 0, sizeof head); memset(vis, 0, sizeof vis); memset(dis, 0x3f, sizeof dis); tot = cnt = 0; register int n = read(), m = read(); for(register int i = 1; i <= m; i++){ register int u = read(), v = read(), w = read(); if(u > v) swap(u, v); if(u == 1) a[++cnt].to = v, a[cnt].val = w; else add(u, v, w), add(v, u, w); } register int ans = 0x3f3f3f3f; memcpy(tmp, head, sizeof head); for(register int i = 0; (1 << i) <= cnt; i++){ memcpy(head, tmp, sizeof tmp); for(register int j = 1; j <= cnt; j++){ if(j & (1 << i)) add(1, a[j].to, a[j].val); else add(a[j].to, n + 1, a[j].val); } spfa(1); ans = min(ans, dis[n + 1]); } if(ans == 0x3f3f3f3f) ans = -1; printf("%d\n", ans); } return 0; }