SSL-ZYC 1500 最短路上的统计

题目大意:
一个无向图上,没有自环,所有边的权值均为1,对于一个点对(a,b),我们要把所有a与b之间所有最短路上的点的总个数输出。


思路:

两遍floyed。

第一遍求出所有点之间的最短路,第二遍枚举每一个点,如果a[i][j]==a[i][k]+a[k][j],那么k点就是最短路径上的一点


代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

int a[101][101],b[101][101],x,y,m,n;

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
     for (int j=1;j<=n;j++)
      a[i][j]=99999999;  //初始化
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        a[x][y]=a[y][x]=1;
    }
    for (int k=1;k<=n;k++)
     for (int j=1;j<=n;j++)
      for (int i=1;i<=n;i++)  //第一遍floyed,求出最短路径
       if (i!=j&&j!=k&&k!=i) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
    for (int k=1;k<=n;k++)
     for (int i=1;i<=n;i++)
      for (int j=1;j<=n;j++)  //第二遍floyed
       if (a[i][k]+a[k][j]==a[i][j]) b[i][j]++;  //判断点k是否是i与j之间最短路的一点
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",b[x][y]+2);  //+2是因为要加上起始点和终点
    }
    return 0;
}
posted @ 2018-03-16 19:25  全OI最菜  阅读(104)  评论(0编辑  收藏  举报