题解 | #双重最短路#
双重最短路
https://ac.nowcoder.com/acm/problem/21736
- 此题dijkstra,spfa,Floyd都可以过.
- 但是我第一次是用的Floyd
- 因为此题n范围非常小,即使是O(n^3)的Floyd算法也不会超时,而且Floyd写起来简单,只有4行代码
Floyd代码:
#include<bits/stdc++.h>
using namespace std;
int n;
const int N=30,INF=0x3f3f3f3f;
int w1[N][N],w2[N][N];
int d1[N],d2[N];
char s1[N][N];
char s2[N][N];
int main()
{
cin>>n;
for(int i=0;i<n;i++)
scanf("%s",s1[i]);
for(int i=0;i<n;i++)
scanf("%s",s2[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(s1[i][j]=='.')
w1[i][j]=INF;
else w1[i][j]=s1[i][j]-'0';
if(s2[i][j]=='.')
w2[i][j]=INF;
else w2[i][j]=s2[i][j]-'0';
}
}
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
w1[i][j]=min(w1[i][j],w1[i][k]+w1[k][j]);
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
w2[i][j]=min(w1[i][j],w1[i][k]+w1[k][j]);
if(w1[0][1]==INF||w2[0][1]==INF)
cout<<-1;
else
cout<<w1[0][1]*w2[0][1];
}spfa算法代码:
#include<bits/stdc++.h>
using namespace std;
int n;
const int N=30,INF=0x3f3f3f3f;
int w1[N][N],w2[N][N];
int d1[N],d2[N];
bool st1[N],st2[N];
char s1[N][N];
char s2[N][N];
void spfa1()
{
memset(d1,0x3f,sizeof d1);
queue<int> q1;
d1[0]=0;
q1.push(0);
while(q1.size())
{
int t=q1.front();
q1.pop();
st1[t]=false;
for(int i=0;i<n;i++)
{
if(d1[i]>d1[t]+w1[t][i])
{
d1[i]=d1[t]+w1[t][i];
if(!st1[i])
{
st1[i]=true;
q1.push(i);
}
}
}
}
}
void spfa2()
{
memset(d2,0x3f,sizeof d2);
queue<int>q2;
d2[0]=0;
q2.push(0);
while(q2.size())
{
int t=q2.front();
q2.pop();
st2[t]=false;
for(int i=0;i<n;i++)
{
if(d2[i]>d2[t]+w2[t][i])
{
d2[i]=d2[t]+w2[t][i];
if(!st2[i])
{
st2[i]=true;
q2.push(i);
}
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
scanf("%s",s1[i]);
for(int i=0;i<n;i++)
scanf("%s",s2[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(s1[i][j]=='.')
w1[i][j]=INF;
else w1[i][j]=s1[i][j]-'0';
if(s2[i][j]=='.')
w2[i][j]=INF;
else w2[i][j]=s2[i][j]-'0';
}
}
spfa1(); spfa2();
if(d1[1]==INF||d2[1]==INF)
cout<<-1;
else
cout<<d1[1]*d2[1];
}