【最短路】House
版权声明:本篇随笔版权归作者Etta(http://www.cnblogs.com/Etta/)所有,转载请保留原地址!
【问题描述】
话说Z4阴差阳错地来到了神秘岛。不久,他们发现,这是一个由n个小岛和一个中心岛组成的群岛,群岛之间有m座桥。令他们感到惊讶的是,这些桥并不是固定不变的,经较长时间的观察,发现它们会随时间作周期性的变化(即桥的两端会不断更换)。
立方很早就留意到远远的那个中心岛了。他发现岛的上空好像有一个很巨大的东西,但实在太远了,看不清楚。此时jakrinchose得意地从身上拿出一个超高倍数望远镜,好像很自豪的样子,因为他平时专门用来看美女的工具此时终于派得上用场了。
“那是一间小屋!架在一棵好大好大的树上!”
“Terrific!我们也许可以暂时在那安顿,好用来遮风避雨!”
于是他们便决定前往中心岛上的那间空中楼阁。Z4的懒惰是出了名的,他们当然希望越早到越好,那么,你能帮帮他们吗?
为方便计算,Z4把小岛按1..n编号,0表示中心岛。Z4一开始在编号为1的小岛上。在岛上行走的时间忽略不计,过桥的时间为1个单位。岛上的桥变化的周期为T,在nT+i(n=0,1,2,…;i=1,2,…,T)时刻岛上的桥为第i种状态,一开始的时刻为1。两个小岛间可能有多条桥相连。在任一时刻,Z4可以选择过桥,也可以原地不动。当然,如果无桥可过,Z4只能在原地等待。
【输入格式】
输入文件house.in的第一行包括三个整数n(1<=n<=80),m(1<=m<=10000)和T(1<=T<=10),分别表示小岛的个数,岛上桥的数量和桥改变的周期T。
接下来分别描述第1..T种状态,每种状态有m行,每行有两个整数a, b(0<=a,b<=n),表示这种状态时小岛a和b有一条桥相连。两状态之间用一空行隔开。
【输出格式】
输出文件house.out仅有一个整数,表示Z4最少得花多少时间到达中心岛。如果Z4无法到达中心岛,则输出“Poor Z4!”。
【输入样例1】
4 5 2
1 2
1 3
1 4
2 0
4 0
1 3
1 3
2 3
4 3
3 0
【输出样例1】
2
【输入样例2】
7 3 2
1 2
1 4
6 0
2 5
3 6
4 7
【输出样例2】
Poor Z4!
一、分析问题
第一遍写直接上SPFA结果完全忽略在原地不动的等待时间,而样例又阴险地没有设这样的数据,于是华丽挂……正解是很巧妙的bell-man,在松弛每一条边的同时计算等待时间找最短路。
二、解决问题
Bell-man+等待时间更新计算
Tips:加1减1什么的很烦人啊,把dis[]理解为时刻更清晰一些
三、代码实现
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 const int A=10000*2*10+20,B=85,C=11,inf=5e8; 6 7 int n,m,t,st,en,tmp,h; 8 int i,j,x,y,k,z; 9 int sum,ex[B],dis[B],pre[B]; 10 bool bo[B][B]; 11 char ch; 12 struct edge{ 13 int from,to,nxt,era; 14 }e[A]; 15 16 void build(int a,int x,int y) 17 { 18 ++sum; 19 e[sum].to=y; 20 e[sum].from=x; 21 e[sum].era=a; 22 } 23 24 void read(int &w) 25 { 26 w=0; 27 ch=getchar(); 28 while(ch>'9'||ch<'0')ch=getchar(); 29 while(ch>='0'&&ch<='9') 30 { 31 w=w*10+ch-'0'; 32 ch=getchar(); 33 } 34 } 35 36 int wait(int x,int d) 37 { 38 int p=d%t;if(!p)p=t; 39 if(p==e[x].era)return 0; 40 for(k=1;k<=t;++k) 41 { 42 p=(d+k)%t;if(!p)p=t; 43 if(p==e[x].era)return k; 44 } 45 } 46 47 void bell() 48 { 49 for(i=0;i<=n;++i)dis[i]=inf; 50 dis[1]=1; 51 for(i=1;i<=n;++i) 52 for(j=1;j<=m;++j) 53 { 54 if(dis[e[j].from]!=inf) 55 { 56 tmp=wait(j,dis[e[j].from]); 57 if(dis[e[j].from]+tmp+1<dis[e[j].to]) 58 dis[e[j].to]=dis[e[j].from]+tmp+1; 59 } 60 } 61 } 62 63 int main() 64 { 65 read(n); 66 read(m); 67 read(t); 68 for(i=1;i<=t;++i) 69 { 70 memset(bo,0,sizeof(bo)); 71 for(j=1;j<=m;++j) 72 { 73 read(x); 74 read(y); 75 if(!bo[x][y]) 76 { 77 bo[x][y]=1; 78 build(i,x,y); 79 build(i,y,x); 80 } 81 } 82 } 83 m*=(2*t); 84 85 bell(); 86 87 if(dis[0]==inf)printf("Poor Z4!\n"); 88 else printf("%d\n",dis[0]-1); 89 return 0; 90 }