51Nod-1649 齐头并进

2024-01-25 17:30
文章标签 51nod 1649 齐头并进

本文主要是介绍51Nod-1649 齐头并进,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1649 齐头并进 
题目来源:  CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 10  难度:2级算法题
 收藏
 关注

在一个叫奥斯汀的城市,有n个小镇(从1到n编号),这些小镇通过m条双向火车铁轨相连。当然某些小镇之间也有公路相连。为了保证每两个小镇之间的人可以方便的相互访问,市长就在那些没有铁轨直接相连的小镇之间建造了公路。在两个直接通过公路或者铁路相连的小镇之间移动,要花费一个小时的时间。

现在有一辆火车和一辆汽车同时从小镇1出发。他们都要前往小镇n,但是他们中途不能同时停在同一个小镇(但是可以同时停在小镇n)。火车只能走铁路,汽车只能走公路。

现在请来为火车和汽车分别设计一条线路;所有的公路或者铁路可以被多次使用。使得火车和汽车尽可能快的到达小镇n。即要求他们中最后到达小镇n的时间要最短。输出这个最短时间。(最后火车和汽车可以同时到达小镇n,也可以先后到达。)


样例解释:

在样例中,火车可以按照 134 行驶,汽车 124 按照行驶,经过2小时后他们同时到过小镇4。


Input
单组测试数据。
第一行有两个整数n 和 m (2≤n≤400, 0≤m≤n*(n-1)/2) ,表示小镇的数目和铁轨的数目。
接下来m行,每行有两个整数u 和 v,表示u和v之间有一条铁路。(1≤u,v≤n, u≠v)。
输入中保证两个小镇之间最多有一条铁路直接相连。
Output
输出一个整数,表示答案,如果没有合法的路线规划,输出-1。
Input示例
4 2
1 3
3 4
Output示例
2
System Message  (题目提供者)
一个最短路径问题,注意要求两次从1到n的最短路径才行

我的思路是将图的邻接矩阵设为布尔型(待会就知道为什么了),然后输入火车线路,此时进行第一次求最短路径,结果保存在ans1里,然后将整个矩阵取非(题意两个城市之间必有铁路或公路,此时就变成了公路的邻接矩阵了),然后再对汽车求一次最短路径,结果保存在ans2里,但是,题目要求火车和汽车必须都到达n才能输出较长的到达时间,所以有三种情况:

1.火车或汽车不能到达,此时输出-1

2.火车比汽车先到达,输出汽车到达所需的时间

3.汽车比火车先到达,输出火车到达所需的时间

下面是代码↓↓↓

#include <stdio.h>
#include <string.h>
#define MAXN 410
#define INF 0x3f3f3f3fbool vis[MAXN];
bool map[MAXN][MAXN];
int path[MAXN];int Dij( int n) {//将最短路径设置为无穷大 memset( path,INF,sizeof(path) );//出发点 vis[1] = true;//更新出发点能直接到达的地方,同时其余地方设置为未到达过 for( int i=2 ; i<=n ; i++ ) {vis[i] = false;if( map[1][i] )path[i] = 1;}for( int i=1 ; i<n ; i++ ) {//记录最小值 int min = INF;//记录最小值的位置 int pos;for( int j=1 ; j<=n ; j++ ) {if( !vis[j] && min>path[j] ) {min = path[ pos=j ];}}//去往最小值 vis[pos] = true;//更新最短路径 for( int j=1 ; j<=n ; j++ ) {if( !vis[j] && map[pos][j] && path[j]>path[pos]+1 )path[j] = path[pos]+1;}}return path[n];
}//邻接矩阵取反 
void Not( int n ) {for( int i=1 ; i<=n ; i++ ) {for( int j=1 ; j<=n ; j++ ) {if( map[i][j] )map[i][j] = false;elsemap[i][j] = true;}}
}//验证矩阵取反正确性 
//void out( int n ) {
//	for( int i=1 ; i<=n ; i++ ) {
//		for( int j=1 ; j<=n ; j++ ) {
//			printf( "%d ",map[i][j] );
//		}
//		printf( "\n" );
//	}
//	printf( "\n");
//}int main() {freopen( "input.txt","r",stdin );int n,m;memset( map,false,sizeof(map) );scanf( "%d%d",&n,&m );int s,e;for( int i=0 ; i<m ; i++ ) {scanf( "%d%d",&s,&e );map[s][e] = map[e][s] = 1;}//保存火车到达时间 int ans1 = Dij(n);
//	out(n);//取反Not(n);
//	out(n);//保存汽车到达时间 int ans2 = Dij(n);//一方不能到达输出-1 if( ans1==INF || ans2==INF )printf( "-1\n" );else {//输出后到达n的最短时间 if( ans1<ans2 )printf( "%d\n",ans2 );elseprintf( "%d\n",ans1 );}
}

这篇关于51Nod-1649 齐头并进的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/644029

相关文章

【51nod】算法马拉松4 F 移数字 【快速求N!%P】【FFT】

传送门:【51nod】算法马拉松4 F 移数字 涉及知识点:多项式求逆,多项式除法,多点插值,阶乘取模。 对于N!%P,复杂度为 O(N−−√log2N−−√) O(\sqrt N \log^2\sqrt N)。 但常数巨大,和暴力算实际复杂度只相差常数= = 这个是可以扩展到组合数取模的~ my  code: my~~code: #include <stdio.h>#includ

独木舟(51Nod-1432)

题目 n个人,已知每个人体重。独木舟承重固定,每只独木舟最多坐两个人,可以坐一个人或者两个人。显然要求总重量不超过独木舟承重,假设每个人体重也不超过独木舟承重,问最少需要几只独木舟? 输入 第一行包含两个正整数n (0<n<=10000)和m (0<m<=2000000000),表示人数和独木舟的承重。 接下来n行,每行一个正整数,表示每个人的体重。体重不超过1000000000,并且每个人的体

51nod 1847 奇怪的数学题

Description 给出 N,K ,请计算下面这个式子: ∑Ni=1∑Nj=1sgcd(i,j)k 其中,sgcd(i, j)表示(i, j)的所有公约数中第二大的,特殊地,如果gcd(i, j) = 1, 那么sgcd(i, j) = 0。 考虑到答案太大,请输出答案对2^32取模的结果. 1≤N≤109,1≤K≤50 样例解释: 因为gcd(i, j)=1时sgcd(i,j)

51nod-1050 循环最大字段和

N个整数组成的循环序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续的子段和的最大值(循环序列是指n个数围成一个圈,因此需要考虑a[n-1],a[n],a[1],a[2]这样的序列)。当所给的整数均为负数时和为0。 例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。 Input 第1行:整数序列的长

51Nod 1163 最高的奖励(贪心+优先队列 并差集)

题目链接:最高的奖励 题目大意 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。 Input 第1行:一个数N,表示任务的数量(2 <= N <= 50000) 第2 - N + 1行,每行2个数

51Nod 1376 最长递增子序列的数量(dp+树状数组)

题目链接 最长递增子序列的题做过不少,让求数量的还是第一次,O(n^2)的代码很好写,但数据范围50000,故无情超时,想了很久,总算有所得。 时间: O(nlog(n)) 空间: O(2*n) 思路 O(n^2)的思路中,每次求以第i个数结尾的最大长度和记录总数都要对前i-1个数进行遍历比较,如果能把这个比较过程转化为对前i项对求和,就可以用树状数组或线段数进行求和优化了。 重

51Nod 1022 石子归并 V2 (划分型dp四边形不等式优化)

石子归并以前做过好几次,是经典划分型dp题之一,一直用的O(n3)的正常dp方法,也从未想过该怎么去优化它。 直到昨天做这道题,n的范围由往常的100改为了1000,老方法 一直超时,苦不堪言,搜到有个四边形不等式的优化方法,看帖子,画式子,拉着学长帮忙推导,总算是大概弄明白了一点。 dp(i,j) = min(dp(i,k)+dp(k+1,j)) + w(i,j);(i < j

51nod 1264 线段相交(几何)

1264 线段相交 基准时间限制:1 秒 空间限制:131072 KB 分值: 0  难度:基础题  收藏  关注 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)。 如果相交,输出"Yes",否则输出"No"。 Input 第1行:一个数T,表示输入的测试数量(1 <= T <= 1000)第2

51nod 1174 区间中最大的数(RMQ)

1174 区间中最大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0  难度:基础题  收藏  关注 给出一个有N个数的序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,最大的数是多少。 例如: 1 7 6 3 1。i = 1, j = 3,对应的数为7 6 3,最大的数为7。(该问题也被称为RMQ问题)

51nod 1134 最长递增子序列(动态规划)

1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0  难度:基础题  收藏  关注 给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。 Input 第1行:1个数N,N为序列的长度(