poj 1932 floyd+bellman-ford
这题把floyd和bellman-ford两种方法都概括了,所以很值得一做。
题意:根据给出的关系图,判断是否存在一条从1到n的路径,且最终的cost值为正值,初始值为100。中间各个room的值有正有负。但在求路径的时候,任何一点的value都不能小于或者等于零,否则这条路就不能通。当然,如果有正环,并且可以从1到n是连通的,那么就一定winnable。
思路:先用floyd判断是否节点的连通性。并且判断1到n是否连通,不连通则hopeless。然后再用bellman-ford来判断1到n是否存在一条正权通路,或者存在正环。当然,dist为负的节点不用去判断,因为如果为负,则这条通路就会成为hopeles。
#include <iostream> #include <fstream> using namespace std; #define MAXN 101 bool map[MAXN][MAXN],connect[MAXN][MAXN]; int value[MAXN],dist[MAXN]; int n; int main() { int a,b,i,j,k; freopen("acm.txt","r",stdin); while(scanf("%d",&n),n!=-1) { memset(value,0,sizeof(value)); memset(map,false,sizeof(map)); memset(dist,-1,sizeof(dist)); memset(connect,false,sizeof(connect)); for(i=1; i<=n; i++) { scanf("%d%d",&value[i],&a); while(a--) { scanf("%d",&b); map[i][b]=true; connect[i][b]=true; //用于判断任意两点间的连通性 } } //floyd判断连通性 for(k=1; k<=n; k++) { for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { if(connect[i][k]&&connect[k][j]) connect[i][j]=true; } } } if(connect[1][n]==false) //1与n不连通 { printf("hopeless\n"); continue; } connect[n][n]=true; //必须加上这个 //Bellman-ford求最长路径 dist[1]=100; //初始值 for(k=1; k<=n; k++) { bool flag=true; for(i=1; i<=n; i++) //遍历每条边 { for(j=1; j<=n ;j++) { if(map[i][j] && connect[j][n] && dist[j]<dist[i]+value[j] && dist[i]>0) {//必须是连通的,且该店与n也是连通的。 并且前一个点的dist非负 dist[j]=dist[i]+value[j]; flag=false; } } } if(flag) { break; } } if(k>n || dist[n]>=0) //有正环或者有正通路 { printf("winnable\n"); } else { printf("hopeless\n"); } } return 0; }
我是一名在校大学生,热爱编程,虽然起步晚了些,但我会努力的。呵呵!
数据结构 算法