Visitors hit counter dreamweaver

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

 

posted @ 2012-05-01 18:53  Jason Damon  阅读(454)  评论(0编辑  收藏  举报