hdu1358 Minimum Transport Cost 按字典序输出最短路径hdu1385

本文介绍了一个经典的图论问题——寻找两个城市间具有最小成本的货物运输路径,包括运输费和过境税。通过Dijkstra算法的改进版实现,并考虑了路径字典序最小的要求。

Minimum Transport Cost

Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3923Accepted Submission(s): 989


Problem Description
These are N cities in Spring country. Between each pair of cities there may be one transportation track or none. Now there is some cargo that should be delivered from one city to another. The transportation fee consists of two parts:
The cost of the transportation on the path between these cities, and

a certain tax which will be charged whenever any cargo passing through one city, except for the source and the destination cities.

You must write a program to find the route which has the minimum cost.

Input
First is N, number of cities. N = 0 indicates the end of input.

The data of path cost, city tax, source and destination cities are given in the input, which is of the form:

a11 a12 ... a1N
a21 a22 ... a2N
...............
aN1 aN2 ... aNN
b1 b2 ... bN

c d
e f
...
g h

where aij is the transport cost from city i to city j, aij = -1 indicates there is no direct path between city i and city j. bi represents the tax of passing through city i. And the cargo is to be delivered from city c to city d, city e to city f, ..., and g = h = -1. You must output the sequence of cities passed by and the total cost which is of the form:

Output
From c to d :
Path: c-->c1-->......-->ck-->d
Total cost : ......
......

From e to f :
Path: e-->e1-->..........-->ek-->f
Total cost : ......

Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.


Sample Input

 
5
0 3 22 -1 4
3 0 5 -1 -1
22 5 0 9 20
-1 -1 9 0 4
4 -1 20 4 0
5 17 8 3 1
1 3
3 5
2 4
-1 -1
0

Sample Output

 
From 1 to 3 :Path: 1-->5-->4-->3Total cost : 21From 3 to 5 :Path: 3-->4-->5Total cost : 16From 2 to 4 :Path: 2-->1-->5-->4Total cost : 17

Source
#include<stdio.h>
#include<string.h>
#define size 1000
int val[size],map[size][size],used[size],min[size],n,start[size],end[size],flag,pre[size];
char s1[1300],s2[1300];
int ok(int n1,int n2,int s)//比较字典序大小
{
	int i,k;
    i=0;
    s1[i++]=n1+'0';
    k=pre[n1];
    while(k!=s)
    {
		s1[i++]=k+'0';
		k=pre[k];
    }
    s1[i++]=s+'0';
    s1[i]='\0';
    strrev(s1);//把字符串翻转过来
    i=0;
    s2[i++]=n1+'0';
    k=n2;//因为依然是n1(j)为最后一个 通过n2(pos)架桥
    while(k!=s)
    {
		s2[i++]=k+'0';
		k=pre[k];
    }
    s2[i++]=s+'0';
    s2[i]='\0';
    strrev(s2);
    if(strcmp(s2,s1)<0)
		return 1;
    else  return 0;
}
void find_short(int s)
{
	int i,j,mm,pos;
	memset(used,0,sizeof(used));
	for(i=1;i<=n;i++)
	{
		min[i]=map[s][i];
		if(map[s][i]!=999999999) //这一步居然忘记了 阿弥陀佛  记住这个千万不能少
			pre[i]=s;
	}
	min[s]=0;used[s]=1;
	for(i=2;i<=n;i++)
	{
		mm=999999999;
		for(j=1;j<=n;j++)
		{
			if(!used[j]&&mm>min[j])
			{
				pos=j;
				mm=min[j];
			}
		}
		if(mm==999999999) break;
		used[pos]=1;
		for(j=1;j<=n;j++)
			if(!used[j]&&min[pos]+map[pos][j]+val[pos]<min[j])
			{
				min[j]=min[pos]+map[pos][j]+val[pos];
				pre[j]=pos;
			}
			else
				if(!used[j]&&min[pos]+map[pos][j]+val[pos]==min[j])
					if(ok(j,pos,s)) pre[j]=pos;//如果pos之前的字典序较小那么更新
	}
}
void print(int s,int e)
{
	int a[size],i,k;
	k=0;
	a[k++]=e;
	i=e;
	while(s!=i)
	{
		i=pre[i];
		a[k++]=i;
	}
	printf("Path: ");
	for(i=k-1;i>0;i--)
		printf("%d-->",a[i]);
	printf("%d\n",a[0]);
}
int main()
{
	int i,j,s,e,num;
	while(scanf("%d",&n)&&n!=0)
	{
		num=0;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
			{
				scanf("%d",&map[i][j]);
				if(map[i][j]==-1) map[i][j]=999999999;
			}
			for(i=1;i<=n;i++)
				scanf("%d",&val[i]);
			while(1)
			{
				scanf("%d %d",&s,&e);
				if(s==-1&&e==-1) break;
				start[num]=s;
				end[num++]=e;
			}
			for(i=0;i<num;i++)
			{
				flag=0;
				find_short(start[i]);
				printf("From %d to %d :\n",start[i],end[i]);
				if(start[i]!=end[i])
					print(start[i],end[i]);
				else printf("Path: %d\n",start[i]);
				printf("Total cost : %d\n",min[end[i]]);
				printf("\n");
			}
	}
	return 0;
}
/*记录路径思路就是加入一个pre[]数组 时时更新每个点前面的点是什么  另外不要忘记从始点出发到i的所有的pre都要赋值初始点
本题要求按字典序找出最短的路径  一开始我感到很恐惧 不知道怎么做  其实心里没有必要那么害怕 只要尝试着一点一点的去做
不要不敢尝试就退却   把大问题分解成一个一个小问题   硬着头皮也要上  (看了别人代码才A了)*/




内容概要:本文介绍了一个关于超声谐波成像中幅度调制聚焦超声所引起全场位移和应变的分析模型,并提供了基于Matlab的代码实现。该模型旨在精确模拟和分析在超声谐波成像过程中,由于幅度调制聚焦超声作用于生物组织时产生的力学效应,包括全场的位移与应变分布,从而为医学成像和治疗提供理论支持和技术超声谐波成像中幅度调制聚焦超声引起的全场位移和应变的分析模型(Matlab代码实现)手段。文中详细阐述了模型构建的物理基础、数学推导过程以及Matlab仿真流程,具有较强的理论深度与工程应用价值。; 适合人群:具备一定声学、生物医学工程或力学背景,熟悉Matlab编程,从事医学成像、超声技术或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于超声弹性成像中的力学建模与仿真分析;②支持高强度聚焦超声(HIFU)治疗中的组织响应预测;③作为教学案例帮助理解超声与组织相互作用的物理机制;④为相关科研项目提供可复用的Matlab代码框架。; 阅读建议:建议读者结合超声物理和连续介质力学基础知识进行学习,重点关注模型假设、偏微分方程的数值求解方法及Matlab实现细节,建议动手运行并修改代码以加深理解,同时可拓展应用于其他超声成像或治疗场景的仿真研究。
### 关于PAT Basic Level Practice的测试点及题目解析 #### 题目难度分级 PAT(Programming Ability Test)是由浙江大学举办的计算机程序设计能力考试,分为不同级别。其中乙级即Basic Level主要面向初学者,考察基本编程技能[^1]。 #### 测试点特点 对于PAT Basic Level中的某些特定题目而言,其测试点设置较为严格。例如,在处理字符串匹配类问题时,需要注意算法逻辑中何时应当终止循环以防止不必要的重复计算;而在涉及数值运算的问题里,则可能因为边界条件而增加复杂度[^3]。 #### 编程语言的选择影响 值得注意的是,尽管大部分简单题目可以作为学习某种新语言的良好实践材料,但在实际操作过程中可能会遇到由于所选语言特性而导致难以通过全部测试点的情况。比如Java在面对部分效率敏感型试题时表现不佳,这可能是由于该语言本身的执行速度相对较慢以及内存管理方式等因素造成的。因此有时不得不转而采用其他更适合解决此类问题的语言版本来完成解答[^2]。 ```cpp #include<bits/stdc++.h> using namespace std; int a[100000]; int c=1; void getPrime(){ int flag=0; for(int i=2;i<105000;i++){ flag=1; for(int j=2;j<=sqrt(i);j++){ if(i%j==0){ flag=0; break; } } if(flag==1) a[c++]=i; } } int main(){ int m,n,i,t=1; scanf("%d %d",&m,&n); getPrime(); for(i=m;i<=n;i++){ if(t%10==1){ printf("%d",a[i]); t++; }else{ printf(" %d",a[i]); t++; } if((t-1)%10==0) printf("\n"); } return 0; } ``` 上述C++代码展示了如何实现一个简单的质数打印功能,并且针对输出格式进行了特殊处理以满足特定要求。这段代码很好地体现了编写高效解决方案的重要性,尤其是在应对像PAT这样的在线评测系统时[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值