Road-最短路

## Road

题目:

JSZKC is the king of his kingdom.

His kingdom has N cities, numbered from 0 to N−1. And the cities are connected by some roads which means you can travel from one city to any other city by roads. Each road have its length.

However, JSZKC wants to delete some roads(maybe 0) and let the kingdom keep the following requirements:

All the cities are still connected.
The number of the rest roads is minimal.
For all the cities, its shortest distance to 0 doesn't change.
JSZKC wants to know how many ways to delete roads with these requirements. Two ways are different if one road is deleted in one way while not in the other way.

As the result may be very large, please output the result mod 1000000007.

Input
The input file contains several test cases, each of them as described below.

The first line of the input contains one integer N(1≤N≤100), giving the cities of the kingdom.
The next follows N lines with each line N integers. Let's define the jth integer in the ith line as f[i][j]. Then it's guaranteed that f[i][j]=f[j][i] and 0≤f[i][j]≤9. If f[i][j]>0, then there is a road with length f[i][j] connecting city i and city j. If f[i][j]=0, then there is no road between city i and j.
There are no more than 100 test cases.

Output
One line per case, an integer indicates the answer.

思路:

题意是给出n个点,给出各边权重,要求删掉一些边,保持各个点联通且剩下的各点到0点的距离最小。
先floyd求各点到0点的最短路,这样就把不是最短距离的边删去了。
然后对于每一个点A,找出每一个中间点,使得点A到0点的距离等于中间点到0点的距离加上点A和中间点的距离(注意不是最短距离)。
有多少个中间点意味着点A有多少条到0点的路径,对于每一个点选取一条路径,所以答案为各个点的中间点个数的乘积。

代码

#include <iostream>
#include <algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<stack>
#define INF 0x3f3f3f3f
using namespace std;
int n;
int map[105][105];
int road[105][105];
char ini[105];
int ans[105];
int main()
{
    while (~scanf("%d", &n))
    {
        memset(ans, 0, sizeof ans);
        for (int i = 0; i < n; i++)
        {
            scanf("%s", ini);
            for (int j = 0; j < n; j++)
            {
                if (ini[j] == '0')
                    map[i][j] = INF;
                else
                    map[i][j] = ini[j] - '0';
                if (i == j)
                    map[i][j] = 0;
            }
        }
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                road[i][j] = map[i][j];
            }
        }
        for (int k = 0; k < n; k++)
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (map[i][j] > map[i][k] + map[k][j])
                    {
                        map[i][j] = map[i][k] + map[k][j];
                    }
                }
            }
        }
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (map[0][i] == map[0][j] + road[i][j]&&i!=j)
                    ans[i]++;
            }
        }
        long long res = 1;
        for (int i = 1; i < n; i++)
        {
            res *= ans[i];
            res %= 1000000007;
        }
        printf("%lld\n", res);
    }
}

猜你喜欢

转载自www.cnblogs.com/booiris/p/10739401.html