hdu1317spfa最长路

#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;
}

Guess you like

Origin blog.csdn.net/weixin_50904510/article/details/120422572