题意:有一个人初始时候有100点能量 然后从房间1走到房间n 每个房间会增加能量或者减少能量
问能否走到该房间
解法:直接用spfa解出最短路即可 但是要注意的是即使存在负环,也有可能走不到终点,这样一来我们就没有办法找出最短路了,我采用了比较笨的办法,通过暴力提高负环的使用率来使得尽量跑的远一些,使得松弛的点更加多,但是只要数据够强 应该还是跑不过去的,还是想不到更好的办法 先存一份错解吧
#include<queue>
#include<vector>
#include<cstdio>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 111111
int head[maxn],cnt,va[maxn],ee;
struct edge{
int v,w,next;
}e[maxn*11];
void init(){
memset(head,-1,sizeof head);
cnt=0;
}
void add(int u,int v){
e[cnt].v=v;e[cnt].w=va[v];
e[cnt].next=head[u];
head[u]=cnt++;
}
int dis[maxn],vis[maxn],n,in[maxn];
int spfa(){
for(int i=1;i<=n;++i){
dis[i]=INT_MAX;
vis[i]=0;in[i]=0;
}
vis[1]=1;
dis[1]=0;
in[1]=1;
queue<int>q;
q.push(1);
while(!q.empty()){
int u=q.front();
q.pop();vis[u]=0;
++in[u];
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w&&(dis[u]+e[i].w<100)){
dis[v]=dis[u]+e[i].w;
if(!vis[v]){
if(in[v]>=100*n)continue;
q.push(v);
vis[v]=1;
}
}
}
}
return 1;
}
vector<int>g[maxn];
int main(){
while(~scanf("%d",&n)){
ee=0;
if(n==-1)break;
int m,x;
for(int i=1;i<=n;++i){
scanf("%d%d",&va[i],&m);
va[i]=-va[i];
ee+=m;
while(m--){
scanf("%d",&x);
g[i].push_back(x);
}
}
init();
for(int i=1;i<=n;++i){
for(vector<int>::iterator it=g[i].begin();it!=g[i].end();it++){
add(i,*it);
}
}
spfa();
// for(int i=1;i<=n;++i)printf("%d ",dis[i]);
// printf("\n");
if(dis[n]<100)printf("winnable\n");
else printf("hopeless\n");
for(int i=0;i<=n;++i)g[i].clear();
}
return 0;
}