Hdu1385

痛苦流涕啊, WA多次才过, 看了网上一些思路才懂。

最小路径还是非常不熟悉。

这题主要是边的权 和 顶点权的最小路径。

此题原意是求 两点间 边的权 + 顶点权 最小值路径 已经路径。

之前看书的就是递归方法找到路径。 、

网上更多是循环方式找到。

觉得循环方式比较容易懂。

 

做这题, 首先是floyd 所有点, 但是在floyd中有所改变。

将平时的

	for(k=1; k<=N; k++)
	{
		for(i=1; i<=N; i++)
		{
			if(i==k || a[i][k]==-1)
				continue;
			for(j=1; j<=N; j++)
			{
				if(a[k][j]==-1 || i==k || j==k)
					continue; 
				fee = a[i][k]+a[k][j]
				if(a[i][j]==-1 || a[i][j] > fee)
				{
					a[i][j] = fee; 
					nex[i][j] = nex[i][k]; 
				}
			}
		}
	}


改为

for(k=1; k<=N; k++)  
    {  
        for(i=1; i<=N; i++)  
        {  
            if(i==k || a[i][k]==-1)  
                continue;  
            for(j=1; j<=N; j++)  
            {  
                if(a[k][j]==-1 || i==k || j==k)  
                    continue;   
                fee = a[i][k]+a[k][j]+b[k];  //加上点得权值b[k]。   
	if(a[i][j]==-1 || a[i][j] > fee)  
	{  
  	    a[i][j] = fee;   
  	    nex[i][j] = nex[i][k];   
	}  
	else if(a[i][j] == fee)    //当权值相等是, 按字典序列记录边集合  
            {  
                if(nex[i][j]>nex[i][k])  
                    nex[i][j] = nex[i][k];  
            }  
        }  
    }  
}  



 

 

一下是我的代码, 虽然是一道比较简单的题目, 由于不熟练, 做起来吃力。

 

#include <iostream>
#include <fstream>

using namespace std; 

int const MAX=100000, Max=1001; 
int a[Max][Max], b[Max], nex[Max][Max]; 
int N, len; 

void floyd()
{
	int i, j, k, fee; 

	for(i=1; i<=N; i++)
		for(j=1; j<=N; j++)
			nex[i][j] = j; 

	for(k=1; k<=N; k++)
	{
		for(i=1; i<=N; i++)
		{
			if(i==k || a[i][k]==-1)
				continue;
			for(j=1; j<=N; j++)
			{
				if(a[k][j]==-1 || i==k || j==k)
					continue; 
				fee = a[i][k]+a[k][j]+b[k]; 
				if(a[i][j]==-1 || a[i][j] > fee)
				{
					a[i][j] = fee; 
					nex[i][j] = nex[i][k]; 
				}
				else if(a[i][j] == fee)
				{
					if(nex[i][j]>nex[i][k])
						nex[i][j] = nex[i][k];
				}
			}
		}
	}
}

void path(int i, int j)
{
	if(j == nex[i][j])
	{
		printf("%d-->%d\n", i, j); 
	}
	else 
	{
		printf("%d-->", i); 
		path(nex[i][j], j);  
	}
}



int main()
{
	//ifstream in("OpenJudgeText.txt"); 

	int i, j; 
	int A, B;

	while(cin>>N && N)
	{
		for(i=1; i<=N; i++)
			for(j=1; j<=N; j++)
				a[i][j] = MAX; 
		memset(b, 0, sizeof b); 

		for(i=1; i<=N; i++)
			for(j=1; j<=N; j++)
				cin>>a[i][j];  
		for(i=1; i<=N; i++)
			cin>>b[i]; 

		floyd(); 	
		while(cin>>A>>B && (A!=-1 || B!=-1))
		{			
			printf("From %d to %d :\n", A, B); 
			
			if(A == B)  //注意A==B时, 路劲就一个数字。				
			printf("Path: %d\n", A);
			else
			{
				printf("Path: ");
				path(A, B);
			}
			printf("Total cost : %d\n\n", a[A][B]);
		}
	}
	return 0; 
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值