Description
Input
Output
Sample Input
3 3 1 2 1 2 3 1 1 3 1 3 3 1 2 1 1 2 3 2 3 1
Sample Output
3 It's impossible.
简单的说floyd算法就是下面这段代码的延伸:
for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=min(d[i][k]+d[k][j],d[i][j]);
(1)算法思想原理:
Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)
从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
(2).算法描述:
a.从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
b.对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。
而对于这题,至少经过俩景区,想想看?这个俩景区有什么用?!!!
如果只是经过一个景区,那么与两景区唯一不同的一种可能情况就是经过一个景区可能就是往返,因此!!!连不成环~~~~
那么!接下来这题不久将问题转化成了与经过俩景区完全无关的成环的最小权值问题吗?这个思想搞清楚了再去看代码会清晰很多!!
#include <iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int a[110][110],d[110][110]; const int maxn=100000000; void init(int n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=maxn,d[i][j]=maxn; } int main() { int m,n; while(~scanf("%d%d",&n,&m)) { init(n); for(int i=0;i<m;i++) { int a1,a2,ww; scanf("%d%d%d",&a1,&a2,&ww); if(a[a1][a2]>ww) a[a1][a2]=a[a2][a1]=d[a1][a2]=d[a2][a1]=ww; } int min0=maxn; for(int k=1;k<=n;k++) { for(int i=1;i<k;i++) for(int j=i+1;j<k;j++) min0=min(min0,d[i][j]+a[i][k]+a[k][j]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=min(d[i][k]+d[k][j],d[i][j]); } if(min0>=maxn) printf("It's impossible.\n"); else printf("%d\n",min0); } return 0; }