JZOJ 3890. 長途旅行【同餘最短路】


題目:

傳送門


題意:

給出一張圖,我們要在恰好爲TT的這個時間點到達nn號城市,每個城市可以被經過多次


分析:

爽快跑一遍同餘最短路,至於mnmn的選取,我們就取與nn號城市相連的權值最小的那條邊
之後如果disn,t%(2mn)tdis_{n,t\%(2*mn)} \leq t就說明可以,否則就不行


代碼:

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
struct node{
	LL to,next,w;
}e[205];
LL ls[55],cnt=0;
void add(LL x,LL y,LL w)
{
	e[cnt]=(node){y,ls[x],w};
	ls[x]=cnt++;
	return;
}
LL dis[55][20005];bool tf[55][20005];int mw;
void dij()
{
	memset(tf,0,sizeof(tf));
	memset(dis,0x3f3f3f3f,sizeof(dis));
	dis[1][0]=0; 
	priority_queue<pair<LL,pair<LL,LL> > > q;
	q.push(make_pair(0,make_pair(1,0)));
	while(q.size())
	{
		LL u=q.top().second.first,mou=q.top().second.second;
		q.pop();
		if(tf[u][mou]) continue;
		tf[u][mou]=1;
		for(LL i=ls[u];~i;i=e[i].next)
		{
			LL v=e[i].to,mov=(mou+e[i].w)%(mw*2);
			if(dis[u][mou]+e[i].w<dis[v][mov])
			{
				dis[v][mov]=dis[u][mou]+e[i].w;
				q.push(make_pair(-dis[v][mov],make_pair(v,mov)));
			}
		}
	}
	return;
}
int main()
{
	LL q=read();
	while(q--)
	{
		LL n=read(),m=read(),t=read();mw=2147483647;
		memset(ls,-1,sizeof(ls));cnt=0;
		for(LL i=1;i<=m;i++)
		{
			int x=read()+1,y=read()+1,w=read();
			add(x,y,w);add(y,x,w);
			if(x==n||y==n) mw=min(mw,w);
		}
		dij();
		if(dis[n][t%(mw*2)]<=t) printf("Possible\n");
		else printf("Impossible\n");
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章