标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4099 Accepted Submission(s):
1136
1、先用Floyd算法判断图的连通性。如果1与n是不连通的,输出hopeless。
2、用Bellman_Ford算法判断是否有正圈,如果某点有正圈,并且该点与第n点是连通的。就输出winnable。当然,没有正圈的情况下,可以到达也是可以的。然后就是如何找正圈的问题。Bellman_Ford算法可以判断有没有负圈。Bellman_Ford是解决最短路问题的,核心是松弛法。如果dist[v]<dist[u]+Map[u][v],则dist[v]=dist[u]+Map[u][v]。在循环n-1次以后,如果还存在dist[v]<dist[u]+Map[u][v],则说明有负圈。这样,我们找正圈也有方法了:dist数组初始化为负无穷。如果dist[v]>dist[u]+Map[u][v],则dist[v]=dist[u]+Map[u][v]。循环n-1次以后,如果还存在dist[v]>dist[u]+Map[u][v],则说明有正圈。
其中,要注意的是。可以往下一房间走的条件是当前的能量值大于0。
题意:有n个房间(n<=100),每个房间有一个点权(第1号房间和第n号房间权值均为0),到达该房间时会自动获得该点权(可能为负权)。给出一些无向边。有一个人,初始有能量值100,初始位置是第1号房间,要走到第n号房间,且路途中不得使身上能量值小于或等于0。能到达第n个房间就算赢,问能否赢。
第一行输入n,接下来n行,第一个输入权值,第二个输入表示从这个房间可到达m个房间,接下来输入m个可到达的房间。
题意:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define M 105 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 struct node 8 { 9 int a,b; 10 } ss[M*M]; 11 int map[M][M],pow[M],n; 12 13 void floyd() //判断是否可以从起点走到终点 14 { 15 int i,j,k; 16 for(k=1; k<=n; k++) 17 for(i=1; i<=n; i++) 18 for(j=1; j<=n; j++) 19 if(!map[i][j]) 20 map[i][j]=map[i][k]&&map[k][j]; 21 } 22 23 int bellman_ford(int len) //判断是否有正环,如果有,且与n是连通的,则输出可以到达 24 { 25 int dis[105]; 26 int i,j,k,a,b; 27 for(i=1; i<=n; i++) 28 dis[i]=-inf; 29 dis[1]=100; 30 for(k=1; k<n; k++) //多次循环,一种算法 31 { 32 for(i=0; i<len; i++) 33 { 34 a=ss[i].a; 35 b=ss[i].b; 36 if(dis[b]<dis[a]+pow[b] && dis[a]+pow[b]>0) 37 dis[b]=dis[a]+pow[b]; 38 } 39 } 40 41 for(i=0; i<len; i++) 42 { 43 a=ss[i].a; 44 b=ss[i].b; 45 if(dis[b]<dis[a]+pow[b] && dis[a]+pow[b]>0 && map[b][n]) 46 return 1; 47 } 48 return dis[n]>0; 49 } 50 51 int main() 52 { 53 int i,j,len,m,x; 54 while(~scanf("%d",&n)) 55 { 56 if(n==-1) break; 57 memset(ss,0,sizeof(ss)); 58 memset(pow,0,sizeof(pow)); 59 memset(map,0,sizeof(map)); 60 len=0; 61 for(i=1; i<=n; i++) 62 { 63 scanf("%d%d",&pow[i],&m); 64 for(j=0; j<m; j++) 65 { 66 scanf("%d",&x); 67 ss[len].a=i; 68 ss[len].b=x; 69 map[i][x]=1; 70 len++; 71 } 72 } 73 floyd(); 74 if(!map[1][n]) //若不能到终点,直接输出不能 75 { 76 printf("hopeless\n"); 77 continue; 78 } 79 if(bellman_ford(len)) 80 printf("winnable\n"); 81 else 82 printf("hopeless\n"); 83 } 84 return 0; 85 }
标签:
原文地址:http://www.cnblogs.com/pshw/p/5398399.html