Interplanetary

題目鏈接:Interplanetary


顯然詢問具有單調性,所以我們可以離線來做。

把點的溫度排序。

然後就變成每次增加一個點,然後快速更新任意兩點之間的最短路,因爲n很小,所以直接floyd即可。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=410,M=1e5+10;
const int inf=0x3f3f3f3f;
int n,m,q,T[N],g[N][N],id[N],v[N][N],res[M],tmp[N][N];
struct node{int u,v,lim,id;};
vector<node> q1,q2;	vector<int> vec;
inline void add(int now){
	for(int i=1;i<=n;i++)	for(int j=1;j<=n;j++)
		g[i][j]=min(g[i][j],g[i][now]+g[now][j]);
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)	for(int j=1;j<=n;j++)	v[i][j]=g[i][j]=(i==j?0:inf);
	for(int i=1;i<=n;i++)	cin>>T[i],id[i]=i,vec.push_back(T[i]);
	for(int i=1,a,b,c;i<=m;i++)	scanf("%d %d %d",&a,&b,&c),v[a][b]=v[b][a]=min(v[a][b],c);
	for(int i=1;i<=n;i++)	for(int j=1;j<=n;j++)	g[i][j]=v[i][j];
	cin>>q;	sort(vec.begin(),vec.end()); vec.erase(unique(vec.begin(),vec.end()),vec.end());
	for(int i=1,a,b,c,d;i<=q;i++){
		scanf("%d %d %d %d",&a,&b,&c,&d);
		if(d)	q2.push_back({a,b,c,i});
		else	q1.push_back({a,b,c,i});
	}
	sort(q1.begin(),q1.end(),[](node a,node b){
		return a.lim<b.lim;
	});
	sort(id+1,id+1+n,[](int a,int b){
		return T[a]<T[b];
	});
	int pos=1;
	for(node i:q1){
		while(pos<=n&&T[id[pos]]<=vec[i.lim-1])	add(id[pos]),pos++;
		res[i.id]=g[i.u][i.v];
	}
	sort(q2.begin(),q2.end(),[](node a,node b){
		return a.lim<b.lim;
	});
	sort(id+1,id+1+n,[](int a,int b){
		return T[a]>T[b];
	});
	pos=1;	reverse(vec.begin(),vec.end());
	for(int i=1;i<=n;i++)	for(int j=1;j<=n;j++)	g[i][j]=v[i][j];
	for(node i:q2){
		while(pos<=n&&T[id[pos]]>=vec[i.lim-1])	add(id[pos]),pos++;
		res[i.id]=g[i.u][i.v];
	}
	for(int i=1;i<=q;i++)
		if(res[i]==inf)	puts("-1");
		else	printf("%d\n",res[i]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章