#include<bits/stdc++.h>
#define ll long long
#define Maxn 1000007
#define Maxm 7000007
using namespace std ;
int tot , n , m , T , k , s , t , back[Maxn] , head[Maxn] , intere[Maxn] ;
ll dis[Maxn] , ans ;
priority_queue<pair<ll , int> > q ;
struct Edge
{
int v , next , w ;
}e[Maxm] , back1[Maxm] ;
void add(int u , int v , int w)
{
e[++ tot].v = v ;
e[tot].w = w ;
e[tot].next = head[u] ;
head[u] = tot ;
}
ll dij()
{
while(! q.empty()) q.pop() ;
memset(dis , 0x3f , sizeof(dis)) ;
dis[s] = 0 ;
q.push(make_pair(0 , s)) ;
for(int i = 1 ; i <= n + 1 ; i ++)
{
while(! q.empty() && dis[q.top().second] != -q.top().first) q.pop() ;
if(q.empty()) break ;
int Temp = q.top().second ;
q.pop() ;
for(int i = head[Temp] ; i ; i = e[i].next)
if(dis[e[i].v] > dis[Temp] + e[i].w)
{
dis[e[i].v] = dis[Temp] + e[i].w ;
q.push(make_pair(-dis[e[i].v] , e[i].v)) ;
}
}
return dis[t] ;
}
int main()
{
cin >> T ;
while(T --)
{
memset(head , 0 , sizeof(head)) ;
cin >> n >> m >> k ;
int u , v , w ;
for(int i = 1 ; i <= m ; i ++)
{
cin >> u >> v >> w ;
add(u , v , w) ;
}
for(int i = 1 ; i <= k ; i ++)
cin >> intere[i] ;
ans = ~ 0ull >> 1 ;
s = n + 1 , t = n + 2 ;
for(int i = 0 ; (1 << i) <= k ; i ++)
{
for(int i = 1 ; i <= tot + 3 ; i ++)
{
back1[i].next = e[i].next ;
back1[i].v = e[i].v ;
back1[i].w = e[i].w ;
}
for(int i = 1 ; i <= n ; i ++)
{
back[i] = head[i] ;
}
memcpy(back , head , (sizeof head[0]) * (n + 3)) ;
for(int j = 1 ; j <= k ; j ++)
{
if(j & (1 << i)) add(s , intere[j] , 0) ;
else add(intere[j] , t , 0) ;
}
ans = min(ans , dij()) ;
for(int i = 1 ; i <= tot + 3 ; i ++)
{
e[i].next = back1[i].next ;
e[i].v = back1[i].v ;
e[i].w = back1[i].w ;
}
for(int i = 1 ; i <= n ; i ++)
{
head[i] = back[i] ;
}
for(int j = 1 ; j <= k ; j ++)
{
if(! (j & (1 << i))) add(s , intere[j] , 0) ;
else add(intere[j] , t , 0) ;
}
ans = min(ans , dij()) ;
for(int i = 1 ; i <= tot + 3 ; i ++)
{
e[i].next = back1[i].next ;
e[i].v = back1[i].v ;
e[i].w = back1[i].w ;
}
for(int i = 1 ; i <= n ; i ++)
{
head[i] = back[i] ;
}
}
cout << ans << endl ;
}
return 0 ;
}
保證輸入數據是有向無環圖 \(n\leq 100000,m\leq 500000,T\leq 5\).
\(n,m\) 分別是點數和邊數。
- 本題的存圖方式是
- 本程序運行的時間復雜度是
- 第 65 行的 \(\texttt{s,t}\) 的作用是什么
- \(s,t\) 一定每次都聯通嗎
- 第 81 行處
j & (1 << i)改為(j >> i) & 1程序運行結果會變化嗎 - 若時限 5s,則不開
-O2該代碼在極限數據情況下有可能超時 - 本程序的作用是求出圖上若干個特殊點的最短距離
dij()內優先隊列存入負權值的作用是- 若輸入數據是
2
6 7 3
1 5 3
2 3 5
1 4 3
5 3 2
4 6 5
4 3 7
5 6 4
1 3 6
7 7 4
5 3 10
6 2 7
1 2 6
5 4 2
4 3 4
1 7 3
7 2 4
1 2 5 3
輸出數據是
答案:洛谷私信找我要
