这题之前以为就是找一条最长路径然后比较最长路径节点a和a相邻节点j,通过公式(dist[a]+dist[j]+mapp[a][j])算出的最大值就可以了
然后发现样例数据中出现了正权回路,那果断会陷入死循环,这样搞得我的思路也陷入死循环了,后来偶然间瞟见某大牛博客上说其实是单源最短路的最大值,
我仔细一想 恍然大悟,其实题目意思是骨牌以一种类似于广搜的倒法开始一路倒下去,那么每到一个关键点就可以发现和它邻接的边都会开始受到影响
那么这样走下去撑到最久的其实是最短路径中的最大值,由于可能终止点出现在边上,那么就需要比较一下最终结点周围的值,然后通过上述公式算出maxx2,
和maxx1做比较,看谁能够更大,那么就是能够撑到最后的情况。 其实样例数据已经很有针对性了,还有个细节要注意下,如果牌数只有1的话那么直接输出0.0,我就是在这里WA了2次
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct node
{
int num;
double value;
};
const int size = 600;
const int eps = 10000000;
double dist[size];
vector <node> mapp[size];
void SPFA(int n, int s)
{
queue <node> que;
bool inque[size] = {false};
for (int i = 1; i <= n; i ++)dist[i] = eps;
node pre;
pre.num = s;
pre.value = 0.00;
que.push(pre);
dist[s] = 0.00;
inque[pre.num] = true;
while (!que.empty()){
pre = que.front();
que.pop();
inque[pre.num] = false;
int k = pre.num;
for (int i = 0; i < mapp[k].size(); i ++){
node t = mapp[k][i];
if (dist[t.num] > dist[pre.num] + t.value){
dist[t.num] = dist[pre.num] + t.value;
if (!inque[t.num]){
inque[t.num] = true;
que.push(t);
}
}
}
}
}
int main()
{
int n, m;
int nc = 0;
while (scanf("%d%d", &n, &m) && (n|m)){
for (int i = 0; i <= n; i ++){
mapp[i].clear();
}
for (int i = 0; i < m; i ++){
node a, b;
scanf("%d%d%lf", &a.num, &b.num, &b.value);
mapp[a.num].push_back(b);
a.value = b.value;
mapp[b.num].push_back(a);
}
printf("System #%d\n", ++ nc);
if (n==1){printf("The last domino falls after %.1lf seconds, at key domino 1.\n\n", 0 );continue;}
SPFA(n, 1);
int ndnum1, ndnum2;
double max1 = -1.0, max2 = -1.0;
for (int i = 1; i <= n; i ++){
if (dist[i] > max1)max1 = dist[i],ndnum1 = i;
}
for (int i = 0; i < mapp[ndnum1].size(); i ++){
int k = mapp[ndnum1][i].num;
double xxx = (mapp[ndnum1][i].value + dist[k] + max1)/2;
if (xxx > max2 ){
max2 = xxx;
ndnum2 = k;
}
}
if (max2 > max1 && ndnum1 > ndnum2)
swap(ndnum1, ndnum2);
max2 > max1?printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n\n", max2, ndnum1, ndnum2):printf("The last domino falls after %.1lf seconds, at key domino %d.\n\n", max1, ndnum1);
}
return 0;
}