1126. 最小花费
毒瘤题。。。卡了好久
本题求乘积最大的路径,咋一看好像是最长路直接无脑跑\(spfa\),事实上\(spfa\)的确能跑过。
但本题也可以用\(dijkstra\)求解,原因是边权有特殊的性质:\(0<w<1\)
这就导致了如果\(s->...->t->...>e\)是\(s\)到\(e\)乘积最大的路径,那么\(s->...->t\)也是\(s\)到\(t\)乘积最大的路径,即满足最优子结构性质。
因此\(dijkstra\)算法每次取权值最大的边相乘即可。
至于\(s->...->t\)为什么一定是最大的,而不会走其他边绕路被更新。
- 因为\(0<w<1\),走其他边绕路必然会越乘越小,必然不会更新
const int N=2010;
vector<PID> g[N];
double dist[N];
bool vis[N];
int n,m,s,e;
void dijkstra()
{
priority_queue<PDI> heap;
heap.push({0,s});
dist[s]=1;
while(heap.size())
{
int t=heap.top().second;
heap.pop();
if(vis[t]) continue;
vis[t]=true;
for(int i=0;i<g[t].size();i++)
{
int j=g[t][i].fi;
double w=g[t][i].se;
if(dist[j] < dist[t]*w)
{
dist[j]=dist[t]*w;
heap.push({dist[j],j});
}
}
}
}
int main()
{
cin>>n>>m;
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
g[a].pb({b,(100-c)/100.0});
g[b].pb({a,(100-c)/100.0});
}
cin>>s>>e;
dijkstra();
printf("%.8f\n",100/dist[e]);
//system("pause");
}