图论——nkoj1636变化的桥(多维spfa)

【Week1】变化的桥

Description

  话说puga来到了神秘岛。他发现,这是一个由n个小岛和一个中心岛组成的群岛,群岛之间有m座桥。令他感到惊讶的是,这些桥并不是固定不变的,经较长时间的观察,发现它们会随时间作周期性的变化(即桥的两端会不断更换)。 
  puga用望远镜看到到远远的那个中心岛上有一间小屋,架在一棵好大好大的树上。于是他决定前往中心岛上的那间空中楼阁。puga当然希望越早到越好,那么,你能帮帮他们吗? 
为方便计算,puga把小岛按1..n编号,0表示中心岛。puga一开始在编号为1的小岛上。在岛上行走的时间忽略不计,过桥的时间为1个单位。岛上的桥变化的周期为T,在nT+i(n=0,1,2,…;i=1,2,…,T)时刻岛上的桥为第i种状态,一开始的时刻为1。两个小岛间可能有多条桥相连。在任一时刻,puga可以选择过桥,也可以原地不动。当然,如果无桥可过,puga只能在原地等待。

Input

  第一行包括三个整数n(1<=n<=80),m(1<=m<=10000)和T(1<=T<=10),分别表示小岛的个数,岛上桥的数量和桥改变的周期T。 
接下来分别描述第1..T种状态,每种状态有m行,每行有两个整数a, b(0<=a,b<=n),表示这种状态时小岛a和b有一条桥相连。两状态之间用一空行隔开。

Output

仅有一个整数,表示puga最少得花多少时间到达中心岛。如果puga无法到达中心岛,则输出“Poor puga!”。

Sample Input

【输入样例1】
4 5 2
1 2
1 3
1 4
2 0
4 0

1 3
1 3
2 3
4 3
3 0
【输入样例2】
7 3 2
1 2
1 4
6 0

2 5
3 6
4 7

Sample Output

【输出样例1】2
【输出样例2】Poor puga!

Hint

1<=n<=80,1<=m<=10000,1<=T<=10

初始位置记住赋初值

#include<cstdio>
#include<iostream>
#include<queue>
#define inf 88888888
using namespace std;
int dis[100][100];//dis[i][j]表示在第j秒到达到达第i号岛的最短时间 
int f[100][100];//spfa标记是否在队列中 
bool map[100][100][100];//map[i][j][k]表示第k秒i号岛与j号岛是否连通 
int n,m,t;
struct node
{
	int num;
	int time;
};//申明一个结构体,num表示岛的编号,time表示到达num号岛的时间 
void spfa()
{
	node fuck;
	int x,k,v,i,j;
	queue<node>q;
	fuck.num=1;
	fuck.time=0;
	f[1][0]=true;//初始位置为1号岛,所以初始化。。。 
	q.push(fuck);
	for(i=0;i<=n;i++)
	{
		for(j=0;j<t;j++)
		{
			dis[i][j]=inf;
		}
	}
	dis[1][0]=0;//一定记住初始位置为0 
	while(q.size())
	{
		x=q.front().num;
		k=q.front().time;
		q.pop();
		f[x][k]=false;
		for(i=0;i<=n;i++)
		{
			v=(k+1)%t;//在第k秒到达x岛,讨论第k+1秒通过x号岛到其他岛时间是否缩短 
			if(map[k][x][i]&&dis[x][k]+1<dis[i][v])
			{
				dis[i][v]=dis[x][k]+1;//如果在第k秒x号岛可以到达i号岛 
									  // 就讨论dis[i][k+1]与dis[x][k]+1的大小 
				if(f[i][v]==false)
				{
					fuck.num=i;
					fuck.time=v;
					f[i][v]=true;
					q.push(fuck);
				}
			}
		}
	}
}
int main(){
	int i,j,k,x,y,ans=inf;
	cin>>n>>m>>t;
	for(i=1;i<=n;i++)
	{
		for(j=0;j<t;j++)
		{
			map[j][i][i]=true; 
		}
	}
	for(i=0;i<t;i++)
	{
		for(j=1;j<=m;j++)
		{
			scanf("%d%d",&x,&y);
			map[i][x][y]=true;
			map[i][y][x]=true;
		}
	}
	spfa();
	for(i=0;i<t;i++)
	{
		ans=min(ans,dis[0][i]);//找答案 
	}
	if(ans>=inf)cout<<"Poor puga!";
	else cout<<ans;
}


你可能感兴趣的:(图论——nkoj1636变化的桥(多维spfa))