最短路存在负环的问题。
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
struct node{
int to;
int next;
int w;
node(){
}
node(int a,int b,int c):to(a),next(b),w(c){
}
}edge[100*100+10];
int head[105];
int dist[106];
int vis[106];
int cnt[106];
int okay[105][106];
int tot;
void add_edge(int u,int v,int w)
{
edge[tot] = node(v,head[u],w);
head[u] = tot++;
}
void flody(int n)
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
okay[i][j] = okay[i][j]|(okay[i][k]&okay[k][j]);
}
void spfa(int n)
{
stack<int>s;
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++){
dist[i] = -105;
}
dist[1] = 100;
s.push(1);
vis[1] = 1;
int flag = 0;
int d;
while(!s.empty())
{
int u = s.top();
s.pop();
vis[u] = 0;
cnt[u]++;
if(cnt[u]>=n)
{
d = u;
flag = 1;
break;
}
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v = edge[i].to;
int w = edge[i].w;
if(dist[v]<dist[u]+w&&dist[u]+w>0)
{
dist[v] = dist[u]+w;
if(!vis[v])
{
vis[v] = 1;
s.push(v);
}
}
}
}
if(flag==1)
{
if(okay[d][n])
printf("winnable\n");
else
printf("hopeless\n");
return ;
}
if(dist[n]>0) printf("winnable\n");
else printf("hopeless\n");
}
int main()
{
int n;
while(scanf("%d",&n))
{
if(n==-1)
break;
int w,t,v;
tot = 0;
memset(head,-1,sizeof(head));
memset(okay,0,sizeof(okay));
for(int i=1;i<=n;i++)
{
scanf("%d",&w);
scanf("%d",&t);
for(int j=0;j<t;j++)
{
scanf("%d",&v);
add_edge(i,v,w);
okay[i][v] = 1;
}
}
flody(n);
if(!okay[1][n])
{
printf("hopeless\n");
continue;
}
spfa(n);
}
return 0;
}