#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
const int inf=0x3f3f3f3f;
int n,m;
int d[maxn],head[maxn],inq[maxn],cnt[maxn],tot;
//d[i]:i点的值。inq[i]:i是否在队列里。cnt[i]:i访问的次数
struct edge{int to,w,nex;}e[maxn*maxn];
void add(int u,int v,int w){
e[++tot]={v,w,head[u]};
head[u]=tot;
}
bool spfa(){
queue<int>q;
int u,v;
memset(d,-inf,sizeof(d));//求最大所以初始为
memset(cnt,0,sizeof(cnt)),memset(inq,0,sizeof(inq));
d[1]=100,inq[1]=1,cnt[1]=1,q.push(1);
while(!q.empty()){
u=q.front(),q.pop(),inq[u]=0;
for(int i=head[u];i;i=e[i].nex){
if(d[u]+e[i].w<=0) continue;
//如果到达这一点的能量大于0,才可以到达这一点,
v=e[i].to;
if(d[u]+e[i].w>d[v]){
d[v]=d[u]+e[i].w;//松弛一下取d值更大的那一个
if(!inq[v]){
if(++cnt[v]>n) continue;
//说明这个点的影响已经传递到它的子节点上了,所以跳出正数环即可
if(cnt[v]==n) d[v]=inf;
//如果次数是n就说明这是一个正数环,然后改变这个点的值,变为INF
q.push(v),inq[v]=1;
}
}
}
}
return d[n]>0;//到n房间还有能量
}
int main(){
int i,j,w;
while(scanf("%d",&n),n+1){
tot=0,memset(head,0,sizeof(head));
for(i=1;i<=n;i++){
scanf("%d%d",&w,&m);
while(m--){
scanf("%d",&j);
add(i,j,w);
}
}
printf("%s\n",spfa()?"winnable":"hopeless");
}
return 0;
}
hdu1317spfa最长路
Guess you like
Origin blog.csdn.net/weixin_50904510/article/details/120422572
Ranking