HDU 1317 && POJ 1932 &&ZJU1935 SPFA

来源:互联网 发布:打印机安装软件 编辑:程序博客网 时间:2024/05/16 06:20

题意:给你可以走的有向边和点的权值,问能否从1走到n且途中的权值和不能<=0;


#include<cstdio>#include<stdlib.h>#include<string.h>#include<string>//#include<map>#include<cmath>#include<iostream>#include <queue>#include <stack>#include<algorithm>#include<set>using namespace std;#define INF 1e8#define inf -0x3f3f3f3f#define eps 1e-8#define LL long long#define maxn 150#define mol 1000000007int n,dis[maxn],map[maxn][maxn],reach[maxn][maxn],e[maxn],vis[maxn];void foyld(){    int i,j,k;for(k=1;k<=n;k++){   for(i=1;i<=n;i++)   {      for(j=1;j<=n;j++)  {        reach[i][j]=reach[i][j]||(reach[i][k]&&reach[k][j]);  }   }}}int SPFA(int s){    queue<int>Q;Q.push(s);dis[s]=100;while(!Q.empty()){   int u=Q.front();   Q.pop();   vis[u]++;   if(vis[u]>=n) return reach[u][n];// 亮点   for(int i=1;i<=n;i++)   {     if(map[u][i]&&dis[u]+e[i]>dis[i]&&dis[u]+e[i]>0) {     dis[i]=dis[u]+e[i]; Q.push(i); }   }}if(dis[n]>0) return 1;elsereturn 0;}int main(){while(scanf("%d",&n)&&n!=-1){ int i,j,num,v; memset(reach,0,sizeof(reach)); memset(map,0,sizeof(map)); memset(vis,0,sizeof(vis)); for(i=0;i<=n+1;i++)    dis[i]=inf; for(i=1;i<=n;i++) {    scanf("%d%d",&e[i],&num);while(num--){   scanf("%d",&v);   map[i][v]=1;   reach[i][v]=1;} } foyld(); if(!reach[1][n]) printf("hopeless\n"); else  {     if(SPFA(1)) printf("winnable\n"); else printf("hopeless\n"); }}return 0; }/*50 1 2-50 1 3-40 2 2 420 1 50 0*/


0 0