首先判断是否有正环,如果有的话那么如果存在从此环到终点的通路则有解
没有的话就直接深搜
是否有正环的判断,用一个数据记录下每个点第一次访问时候的能量,然后深搜的时候搜回来如果能量比之前的大说明存在正环。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int maps[101][101];
int visitedD[101];
int visitedB[101];
int energy[101];
int q[101];
int no_of_rooms;
int BFS_F(int);
bool DFS_C(int des,int current_e)
{
if(des==no_of_rooms-1)
return true;
for(int i=0;i<no_of_rooms;++i)
{
if(maps[des][i]&&t_e+energy[i]>0)
{
if(!visitedB[i])//说明是第一次来
{
visitedB[i]=current_e+energy[i];
if(DFS_C(i,visitedB[i]))
{
return true;
}
}
else if(current_e+energy[i]>visitedB[i]&&BFS_F(i))//第二次来的时候判断下是不是正环
{
return true;
}
}
}
return false;
}
int BFS_F(int u)
{
int front,rear;
rear=0;front=0;
memset(visitedD,0,sizeof(visitedD));
visitedD[u]=1;
q[rear++]=u;
while(front<rear)
{
int kk=q[front++];
for(int i=0;i<no_of_rooms;++i)
{
if(maps[kk][i]&&!visitedD[i])
{
if(i==no_of_rooms-1)
return 1;
visitedD[i]=1;
q[rear++]=i;
}
}
}
return 0;
}
void ini()
{
for(int i=0;i<101;++i)
{
visitedB[i]=0;
visitedD[i]=0;
for(int j=0;j<101;++j)
{
maps[i][j]=0;
}
}
}
int main()
{
int m,k;
while(scanf("%d",&no_of_rooms)!=EOF)
{
ini();
memset(maps,0,sizeof(maps));
if(no_of_rooms==-1)
return 0;
for(int j=0;j<no_of_rooms;++j)
{
scanf("%d",&energy[j]);
scanf("%d",&m);
for(int i=0;i<m;++i)
{
scanf("%d",&k);
maps[j][k-1]=1;
}
}
if(DFS_C(0,100))
{
printf("winnable\n");
}
else
{
printf("hopeless\n");
}
}
}