UVA_10557
This question is actually the longest path from the start point to the end point.
However, since the weight value cannot be negative when passing through each point, we need to initialize 0 when initializing the distance from array d. The Bellman-Ford Algorithm Optimized in the queue is used to find the longest path, but there are still some details to be aware.
Of course we can choose d [n]> 0 when using this algorithm to jump out of the loop to reduce the amount of computing, but we will also find an example of the algorithm crash, for example, if there is a positive circle in a certain position, but the positive circle cannot reach the end point, the program will continue to run. But in the same way, we can't jump in circles, because after all, there are still some positive circles that can reach the final point. This requires us to determine which positive circles can reach the destination.
Therefore, we can start preprocessing before finding the longest path and find out all the points that can reach the destination. A better way is to start reverse searching from the destination, then Mark the searched points in sequence. If the last starting point is not marked, output hopeless directly.
When we use the Bellman-Ford Algorithm Optimized in the queue, we can add a judgment on the judgment condition to determine whether the end point can be reached. If the end point can be reached, we will perform the longest operation.
#include<stdio.h>
#include<string.h>
int G[110][110],w[110],d[110],n;
int q[110],inq[110],inedq[110];
int vis[110],reach[110];
void dfs(int v)
{
int u;
for(u=1;u<=n;u++)
if(G[u][v]&&!vis[u])
{
vis[u]=1;
reach[u]=1;
dfs(u);
}
}
int main()
{
int i,j,k,u,v,num,front,rear,flag;
while(1)
{
scanf("%d",&n);
if(n==-1)
break;
memset(G,0,sizeof(G));
for(u=1;u<=n;u++)
{
scanf("%d",&w[u]);
scanf("%d",&num);
for(i=0;i<num;i++)
{
scanf("%d",&v);
G[u][v]=1;
}
}
memset(vis,0,sizeof(vis));
memset(reach,0,sizeof(reach));
reach[n]=1;
dfs(n);
if(!reach[1])
{
printf("hopeless\n");
continue;
}
memset(inq,0,sizeof(inq));
memset(inedq,0,sizeof(inedq));
memset(d,0,sizeof(d));
front=rear=0;
d[1]=100;
q[rear++]=1;
inq[1]=1;
inedq[1]++;
flag=0;
while(front!=rear)
{
u=q[front++];
if(front>n)
front=0;
inq[u]=0;
for(v=1;v<=n;v++)
if(G[u][v]&&reach[v]&&d[u]+w[v]>d[v])
{
d[v]=d[u]+w[v];
if(!inq[v])
{
q[rear++]=v;
if(rear>n)
rear=0;
inq[v]=1;
if(inedq[v]++>n)
{
flag=1;
break;
}
}
}
if(d[n]>0||flag)
break;
}
if(d[n]>0||flag)
printf("winnable\n");
else
printf("hopeless\n");
}
return 0;
}