HDU 1385(带边权与点权的最短路)

题目描述不清 字典序排列并非是字符串比较 而是点序列号的比较 终点与起点相同 路径只为顶点

 

50次WA后AC 够变态

#include  < iostream >
#include 
< string >
using   namespace  std;

const   long  lmax = 0x5FFFFFFF ;
const   long  MAXN = 500 ;

long  hash[MAXN][MAXN];
bool  vist[MAXN];
long  dis[MAXN];
long  pre[MAXN];
long  cost[MAXN];
long  tax[MAXN];
long  from,to;
long  N;

inline 
void  convert( long  r,  char   * key)
{
    
char  temp[ 20 ];
    
long  i = 0 ;
    
if  (r == 0 )
    {
        key[
0 ] = ' 0 ' ;
        key[
1 ] = ' \0 ' ;
        
return ;
    }

    
while (r)
    {
        temp[i]
= ' 0 ' + r % 10 ;
        r
= r / 10 ;
        
++ i;
    }
    
-- i;
    
long  j = 0 ;
    
for  (;i >= 0 ; -- i, ++ j)
    {
        key[j]
= temp[i];
    }
    key[j]
= ' \0 ' ;

}

inline 
bool  lexically( long  u, long  j)
{
    
long  path_1[ 1000 ];
    
long  path_2[ 1000 ];
    
    
long  i = 0 ;

    path_1[i
++ ] = j;
    path_1[i
++ ] = u;

    
while  (pre[u] != from)
    {
        path_1[i
++ ] = pre[u];
        u
= pre[u];
    }

    path_1[i
++ ] = from;

    
long  len1 = i - 1 ;

    i
= 0 ;

    path_2[i
++ ] = j;

    
while  (pre[j] != from)
    {
        path_2[i
++ ] = pre[j];
        j
= pre[j];
    }

    path_2[i
++ ] = from;

    
long  len2 = i - 1 ;

    
long  len = len1 < len2 ? len1:len2;

    
for  (i = 0 ;i <= len; ++ i)
    {
        
if  (path_1[len1 - i] < path_2[len2 - i])
        {
            
return   true ;
        }
        
        
if  (path_1[len1 - i] > path_2[len2 - i])
        {
            
return   false ;
        }
    }

    
if (len1 < len2)
    {
        
return   true ;
    }

    
return   false ;
}

inline 
long  Dijkstra()
{
    
long  i,j;
    
long  m_max;
    
long  u;

    memset(vist,
0 , sizeof (vist));
    memset(cost,
0 , sizeof (cost));

    
for  (i = 1 ;i <= N; ++ i)
    {
        
if  (hash[from][i] != lmax)
        {
            dis[i]
= hash[from][i];   
            pre[i]
= from;
        }
        
else
        {
            dis[i]
= lmax;
        }
    }
    
    dis[from]
= 0 ;
    vist[from]
= true ;
    
    
for  (i = 1 ;i < N; ++ i)
    {
        m_max
= lmax;
        
for  (j = 1 ;j <= N; ++ j)
        {
            
if  ( ! vist[j] && dis[j] + cost[j] < m_max)
            {
                u
= j;
                m_max
= dis[j] + cost[j];
            }
        }
        
        
if  (m_max == lmax)
        {
            
break ;
        }
        
        vist[u]
= true ;        
        
        
for  (j = 1 ;j <= N; ++ j)
        {
            
if  ( ! vist[j] && hash[u][j] != lmax)
            {
                
if (hash[u][j] + cost[u] + dis[u] + tax[u] < dis[j] + cost[j])
                {
                    dis[j]
= hash[u][j] + dis[u];
                    cost[j]
= cost[u] + tax[u];
                    pre[j]
= u;
                }
                
else   if  (hash[u][j] + cost[u] + dis[u] + tax[u] == dis[j] + cost[j])
                {
                    
if  (lexically(u,j))
                    {
                        dis[j]
= hash[u][j] + dis[u];
                        cost[j]
= cost[u] + tax[u];
                        pre[j]
= u;
                    }
                }
            }
        }
    }
    
return  dis[to] + cost[to];
}

inline 
string  Get_Path()
{
    
string  path;
    path.erase();
    
long  r = pre[to];
    
char  key[ 20 ];
    convert(to,key);
    path
= key;
    
while  (from != r)
    {
        convert(r,key);
        path
= " --> " + path;
        path
= key + path;
        r
= pre[r];
    }
    convert(from,key);
    path
= " --> " + path;
    path
= key + path;
    
return  path;
}

int  main()
{
    
while  (scanf( " %ld " , & N) != EOF)
    {
        
if  (N == 0 )
        {
            
break ;
        }

        
long  i,j;

        
for  (i = 1 ;i <= N; ++ i)
        {
            
for  (j = 1 ;j <= N; ++ j)
            {
                scanf(
" %ld " , & hash[i][j]);
                
if  (hash[i][j] ==- 1 )
                {
                    hash[i][j]
= lmax;
                }
            }
        }
        
        
for  (i = 1 ;i <= N; ++ i)
        {
            scanf(
" %ld " , & tax[i]);
        }
        
        
while  ( 1 )
        {
            scanf(
" %ld %ld " , & from, & to);
            
if  (from ==- 1 && to ==- 1 )
            {
                
break ;
            }
            
            
if  (from == to)
            {
                printf(
" From %ld to %ld :\n " ,from,to);
                printf(
" Path: %ld\n " ,from);
                printf(
" Total cost : %ld\n\n " , 0 );
            }
            
else
            {
                
long  price = Dijkstra();
                printf(
" From %ld to %ld :\n " ,from,to);
                printf(
" Path: %s\n " ,Get_Path().data());
                printf(
" Total cost : %ld\n\n " ,price);
            }
           
        }
        
    }
    
return   0 ;
}

转载于:https://www.cnblogs.com/zhuangli/archive/2008/08/12/1266308.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值