http://acm.hdu.edu.cn/showproblem.php?pid=6026
当时打重现赛的时候一直不懂题目到底什么意思,大概是快结束的前30分钟才看到了讨论里面有人解释6是怎么来的。
题目大意:给出一个无向图,他们的距离就是输入的矩阵,而且0是当成不通来处理,这个距离只有0到9。现在,要保证从第一个点开始走到最后一个点,而且途中到每一个点的距离都要是最短的。问这样的路有多少条。
解法:我们跑一遍dijkstra,因为dijkstra的距离是从INF向下松弛的,如果松弛条件成立,那么我们重置到这个点的距离,如果到这个点的距离刚好等于G[pos][i]+dis[pos],那么到这个点的最短路径+1。最后,我们把每个点的最短路径相乘,就是答案。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int cnt[55], n;
int G[55][55], dis[55];
void myDijkstra()
{
memset(cnt, 0, sizeof(cnt));
bool vst[55] = {0};
int Min, pos;
for(int i = 0; i < n; i++)
dis[i] = INF;
dis[0] = 0;
cnt[0] = 1;
for(int i = 0; i < n; i++)
{
Min = INF;
for(int j = 0; j < n; j++)
{
if(!vst[j] && dis[j] < Min)
{
Min = dis[j];
pos = j;
}
}
if(Min == INF)
break;
vst[pos]=1;
for(int j = 0; j < n; j++)
{
if(!G[pos][j])
continue;
if(!vst[j] && dis[j] > dis[pos] + G[pos][j])
{
dis[j] = dis[pos] + G[pos][j];
cnt[j] = 0;
}
if(dis[j] == dis[pos] + G[pos][j])
cnt[j]++;
}
}
}
int main()
{
long long ans;
char ch;
while(cin >> n)
{
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
{
ch = getchar();
while(ch < '0' || ch > '9')
ch = getchar();
G[i][j] = ch - 48;
}
myDijkstra();
ans = 1;
for(int i = 0; i < n; i++)
ans = (ans * cnt[i]) % mod;
cout << ans << endl;
}
return 0;
}