题目链接:http://poj.org/problem?id=1135
代码参考:《图论算法理论、实现及应用》——北京大学出版社
题目大意:在多米诺骨牌中有几张关键牌,这些两张关键牌a,b之间有c张普通牌,问,推到第一张关键牌,多少时间可以把它全部推到,最后一张推到的牌,它的位置在哪里。
算法:dijkstra
在POJ上交了n遍G++WA,C++AC,伤不起
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n, m;
const int inf = 0x7ffffff;
int dist[1000], map[1000][1000];
int vis[1234];
void dijk(int k)
{
int i, j;
memset(vis, 0, sizeof(vis));
for(i = 1; i <= n; i ++)
{
dist[i] = map[k][i];
}
dist[k] = 0;
vis[k] = 1;
for(i = 1; i < n; i ++)
{
int minn = inf;
for(j= 1; j <= n; j ++)
{
if(!vis[j] && dist[j] < minn)
{
minn = dist[j];
k = j;
}
}
if(minn == inf)
break;
vis[k] = 1;
for(j = 1; j <= n; j ++)
{
if(!vis[j] && map[k][j] < inf && dist[j] > map[k][j] + dist[k])
dist[j] = map[k][j] + dist[k];
}
}
double maxn = -inf ;
int pos;
for(i = 1; i <= n; i ++)
if(maxn < dist[i])
{
pos = i;
maxn = dist[i];
}
double maxm = -inf;
int pos1, pos2;
for(i = 1; i < n; i ++)
for(j = i+1; j <= n; j ++)
if(map[i][j] < inf && (dist[i] + dist[j] + map[i][j]) / 2.0 > maxm)
{
pos1 = i, pos2 = j;
maxm = (dist[i] + dist[j] + map[i][j]) / 2.0;
}
if(maxn >= maxm )
{
printf("%.1lf seconds, at key domino %d.\n\n", maxn, pos);
}
else
printf("%.1lf seconds, between key dominoes %d and %d.\n\n", maxm, pos1, pos2);
// printf("pos2 = %d\n", pos2);
}
int main()
{
int ica = 1;
while(scanf("%d%d", &n, &m))
{
if(!n && !m)
break;
int i, j;
for(i= 1; i <= n; i ++)
for(j = 1; j <= n; j ++)
{
map[i][j] = inf;
}
int a, b, c;
for(i = 1; i <= m ; i ++)
{
scanf("%d%d%d", &a, &b, &c);
map[a][b] = c;
map[b][a] = c;
}
printf("System #%d\nThe last domino falls after ", ica ++ );
dijk(1);
}
return 0;
}