出給本校學弟的初賽模擬


#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\) 分別是點數和邊數。

  1. 本題的存圖方式是
  2. 本程序運行的時間復雜度是
  3. 第 65 行的 \(\texttt{s,t}\) 的作用是什么
  4. \(s,t\) 一定每次都聯通嗎
  5. 第 81 行處 j & (1 << i) 改為 (j >> i) & 1 程序運行結果會變化嗎
  6. 若時限 5s,則不開 -O2 該代碼在極限數據情況下有可能超時
  7. 本程序的作用是求出圖上若干個特殊點的最短距離
  8. dij() 內優先隊列存入負權值的作用是
  9. 若輸入數據是
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

輸出數據是

答案:洛谷私信找我要


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM