【題解】洛谷P3946 小鳥的點心(spfa)

稍微思考可以發現這道題目是最短路問題,但我們有一些特殊的情況需要考慮。

當積雪增長速度q=0時,我們設每個點雪漲到無法通行的位置的時間(因爲南小鳥的速度是1m/s 實際上路程在數值上就是時間了)是最大值INF(因爲雪不能漲了嘛),否則用(l[i]-h[i])/q(注意這裏的差和除數都是double類型,最後轉化成int類型)計算出時間來。然後我們建圖跑spfa,這裏更新最短路的條件有兩個:1.下一個目標點不是家,這樣在普通最短路的基礎上需要判斷更新的最短路應當比下一個目標點的時間小(等於也不行 會困在那裏的qwq) 2.下一個目標點是家,題面告訴我們不用考慮那裏的積雪情況,判斷普通的最短路條件即可。然後跑出來如果小於等於時間限制g就輸出答案,否則輸出"wtnap wa kotori no oyatsu desu!"。

(我永遠喜歡南小鳥(然而我是繪廚))

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
const int maxn=100010;
const int maxm=500010;
int head[maxn],nnext[maxm*2],to[maxm*2],length[maxm*2],dis[maxn];
int kotori[maxn],h[maxn],l[maxn];
bool b[maxn];
int n,m,s,t,g,q,tot;
int ans=0;
void add(int x,int y,int l)
{
	tot++;
	nnext[tot]=head[x];
	head[x]=tot;
	to[tot]=y;
	length[tot]=l;
}
bool spfa()
{
	queue <int> q;
	memset(b,false,sizeof(b));
	for(int i=1;i<=n;i++)
	{
		dis[i]=1e9;
	}dis[s]=0;
	b[s]=true;
	q.push(s);
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		b[now]=false;
		for(int i=head[now];i;i=nnext[i])
		{
			int y=to[i];
			if((dis[y]>dis[now]+length[i]&&dis[now]+length[i]<kotori[y]&&y!=t)||(dis[y]>dis[now]+length[i]&&y==t))
			{
				dis[y]=dis[now]+length[i];
				if(!b[y])
				{
					b[y]=true;
					q.push(y);
				}
			}
		}
	}
	ans=dis[t];
	if(ans==1e9) return false;
	else return true;
}
int main()
{
	scanf("%d%d%d%d%d%d",&n,&m,&s,&t,&g,&q);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&h[i],&l[i]);
	}
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	for(int i=1;i<=n;i++)
	{
		if(q==0)
		{
			kotori[i]=1e9;
			continue;
		}
		else
		{
			kotori[i]=(int)((double)(l[i]-h[i])/(double)q);
		}
	}
	if(spfa()&&ans<=g) cout<<ans<<endl;
	else cout<<"wtnap wa kotori no oyatsu desu!"<<endl;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章