时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]
题目描述
小X有很多朋友,分布在N个城市。
这N个城市之间,有些有直接的道路,有些是间接联通的(保证任何两个城市都可以相互到达。)。
但是,经过每条道路都是有代价的,于是,小X希望你来帮他找出一个城市,使得他的所有朋友到这个城市的代价最小。
输入
输入共2* N+1行,
其中第一行为一个整数N,
第2~N+1行
每行有N个整数、表示两个城市间的代价,(0表示不直接连通)
第n+2~2*N+1行
每行一个整数。表示每个城市中小X的朋友数。
输出
输出有两行。
第一行为你选中的城市
第二行为最小需要的代价。
样例输入 Copy
5
0 1 2 0 0
1 0 0 0 20
2 0 0 10 0
0 0 10 0 1
0 20 0 1 0
2
3
4
5
6
样例输出 Copy
4
109
提示
对于100%的数据,n<=200,输出保证不超过long long int
对于任意一个城市,其余所有城市的朋友只有经过最短路时才满足所有的朋友到该城市的代价最小,因此可以先求任意两点的最短路径,然后再求最小的代价。
题目数据量较小,采用floyd算法。floyd算法是求解最短路径的一种算法,采用动态规划的思想。我们可以这样想,从i点到j点,有两种方案,一是直接从i到j,另一种是从i经过第三个点k(若干个)到达j。由此floyd算法的思路就出来了。对于任意的i、j两点,遍历所有的点,寻找从i直接到j和从i经过第三个点到j的最小值,遍历结束后求得的最小值就是从i到j的最短路径。
floyd算法的核心代码就4行,直接套就完事了。
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
path[i][j]=min(path[i][j],path[i][k]+path[k][j]);
#include<cstdio>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int path[205][205];//表示任意两点的距离
int fri[205];
int main()
{
int n,i,j,k,dis,ans,city,t;
scanf("%d",&n);
for(i=1;i<=n;i++) //(1)同一个点(i到i)之间的距离为0
{ //(2)0表示不直接连通,距离设为0x3f3f3f3f(可以表示无穷大)
for(j=1;j<=n;j++) //(3)连通的不同的点的距离设为dis
{
scanf("%d",&dis);
if(i==j)path[i][j]=0;
else
{
if(dis==0)path[i][j]=inf;
else path[i][j]=dis;
}
}
}
for(i=1;i<=n;i++)scanf("%d",&fri[i]);
ans=inf;
for(k=1;k<=n;k++)//floyd算法核心代码
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
path[i][j]=min(path[i][j],path[i][k]+path[k][j]);
}
}
}
for(i=1;i<=n;i++)//寻找最小代价
{
t=0;
for(j=1;j<=n;j++)
{
t+=fri[j]*path[i][j];
}
if(ans>t)
{
ans=t;
city=i;
}
}
printf("%d\n%d",city,ans);
return 0;
}
/**************************************************************
Language: C++
Result: 正确
Time:83 ms
Memory:1284 kb
****************************************************************/