列表

详情


NC21736. 双重最短路

描述

有一张n个点的无向图,标号为0到n-1,图中的每条边有两个权值,现在让你求出从0到1的最短路,最短路的定义是W1*W2,W1为路径上第一种权值的和,W2为路径上第二种权值的和,如果没有最短路,输出-1

输入描述

第一行输入一个整数n (2 ≤ n ≤ 20)

接下来n行每行n个字符,第i行的第j个字符表示weight1[i][j]
再接下来n行每行n个字符,第i行的第j个字符表示weight2[i][j]

所有的字符要么是数字要么是'.'

第i行的第j个字符是数字表示ij两个点联通,且权值为这个数字
否则表示不联通

输出描述

输出一个整数

示例1

输入:

4    	
..14
..94
19..
44..
..94
..14
91..
44..

输出:

64

示例2

输入:

4
..14
..14
11..
44..
..94
..94
99..
44..

输出:

36

示例3

输入:

6    
.....9
..9...
.9.9..
..9.9.
...9.9
9...9.
.....9
..9...
.9.9..
..9.9.
...9.9
9...9.

输出:

2025

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 4ms, 内存消耗: 472K, 提交时间: 2021-08-11 16:13:47

#include<iostream>
#include<cstring>

using namespace std;
int n;
const int maxn=22;
int f[maxn][maxn][2];

int main(){
	cin>>n;
	memset(f,0x3f3f3f3f,sizeof(f));
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			char c;cin>>c;
			if(c!='.')f[i][j][0]=c-'0';
			if(i==j) f[i][j][0]=0;
		}
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			char c;cin>>c;
			if(c!='.')f[i][j][1]=c-'0';
			if(i==j) f[i][j][1]=0;
		}	 
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j){
				f[i][j][0]=min(f[i][k][0]+f[k][j][0],f[i][j][0]);
				f[i][j][1]=min(f[i][k][1]+f[k][j][1],f[i][j][1]);
			}
	if(f[1][2][0]==0x3f3f3f3f || f[1][2][1]==0x3f3f3f3f) cout<<"-1";
	else cout<<f[1][2][0]*f[1][2][1];return 0;
}

上一题