链接:https://ac.nowcoder.com/acm/problem/21736
来源:牛客网
题目描述
有一张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两个点联通,且权值为这个数字
否则表示不联通
输出描述:
输出一个整数
#include <iostream>
#include <vector>
using namespace std;
struct E{
int next;
int c;
//int c2;
};
vector<E>edge[101];
vector<E>edge1[101];
bool mark[101];
char a[21][21];
int dis[21];
int m;
int dis1[21];
int main()
{
cin>>m;
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
if(a[i][j]!='.')
{
E tmp;
tmp.c=a[i][j]-'0';
tmp.next=i;
edge[j].push_back(tmp);
}
}
}
for(int i=0;i<m;i++)
{
dis[i]=-1;
mark[i]=false;
}
dis[0]=0;
mark[0]=true;
int newp=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<edge[newp].size();j++)
{
int t=edge[newp][j].next;
int c=edge[newp][j].c;
if(mark[t]==true) continue;
if(dis[t]==-1||dis[t]>dis[newp]+c)
{
dis[t]=dis[newp]+c;
}
}
int minn=1231231;
for(int j=0;j<m;j++)
{
if(mark[j]==true) continue;
if(dis[j]==-1) continue;
if(dis[j]<minn)
{
minn=dis[j];
newp=j;
}
}
mark[newp]=true;
}
///
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
if(a[i][j]!='.')
{
E tmp;
tmp.c=a[i][j]-'0';
tmp.next=i;
edge1[j].push_back(tmp);
}
}
}
for(int i=0;i<m;i++)
{
dis1[i]=-1;
mark[i]=false;
}
dis1[0]=0;
mark[0]=true;
newp=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<edge1[newp].size();j++)
{
int t=edge1[newp][j].next;
int c=edge1[newp][j].c;
if(mark[t]==true) continue;
if(dis1[t]==-1||dis1[t]>dis1[newp]+c)
{
dis1[t]=dis1[newp]+c;
}
}
int minn=1231231;
for(int j=0;j<m;j++)
{
if(mark[j]==true) continue;
if(dis1[j]==-1) continue;
if(dis1[j]<minn)
{
minn=dis1[j];
newp=j;
}
}
mark[newp]=true;
}
if(dis[1]==-1||dis1[1]==-1)
{
cout<<"-1"<<endl;
}
else
{
//cout<<dis[1]<<endl;
cout<<dis[1]*dis1[1]<<endl;
}
return 0;
}