这个题的话有点超出我的能力范围了。。。需要一个BFS+一个DFS,DFS来遍历,如果找到一个点能走2次,并且第次走到比第一次走到的能力值要大,之后用BFS判断能不能通过这个点走到终点,如果能的话,就可以走到终点。。。
能力问题吧就是想不到,所以上网查了一下代码,之前自己用 优先队列进行BFS遍历一直在超时。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXD 1000 + 10
int n;
int room[MAXD];
int G[MAXD][MAXD];
int visa[MAXD];
int E[MAXD];
bool bfs(int u){
memset(visa,0,sizeof(visa));
int stacks[MAXD];
int front=0,back=0;
stacks[back++]=u;
visa[u]=1;
while(front<back){
int q=stacks[front++];
for(int i(1);i<=n;i++){
if(G[q][i]&&!visa[i]){
visa[i]=1;
if(i==n) return true;
else {
stacks[back++]=i;
}
}
}
}
return false;
}
bool dfs(int u,int e){
if(u==n) return true;
for(int i(1);i<=n;i++){
int x = e + room[i];
if(G[u][i]&&x>0){
if(!E[i]){
E[i]=x;
if(dfs(i,E[i])) return true;
}
else if(x>E[i]){
if(bfs(i)) return true;
}
}
}
return false;
}
int main()
{
while(scanf("%d",&n)&&n>0){
memset(E,0,sizeof(E));
memset(G,0,sizeof(G));
for(int i(1);i<=n;i++){
int x,y,z;
scanf("%d%d",&x,&y);
room[i]=x;
for(int j(0);j<y;j++){
scanf("%d",&z);
G[i][z]=1;/*单向图*/
}
}
if(dfs(1,100))
printf("winnable\n");
else
printf("hopeless\n");
}
return 0;
}