题目:https://www.luogu.org/problemnew/show/P1576
或者http://111.231.101.32/problem.php?id=1002(自建OJ,欢迎光临)
分析:
结点最多2000个,所以,不可能用floyed,否则超时,采用dijkstra算法,时间复杂度O(n^2)。
本题是求源点s到终点e的最大转账率,所以初始化定义dis[1..n]=0,dis[s]=1,松驰代码是
/*v是新染白的点,j是与之邻接的蓝点,f[v][j]是转帐率*/
if(dis[j]<dis[v]*f[v][j]) dis[j]=dis[v]*f[v][j];
灵活使用算法,将问题转换成已经掌握的模型,是noiper需要为之不断奋斗努力的。
AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n,m;
bool vis[2005];
double f[2005][2005],dis[2005];
void dijkstra(int s){
dis[s]=1;
int v;
for(int i=1;i<=n;i++){
double maxx=0;
for(int j=1;j<=n;j++){
if(!vis[j] && maxx<dis[j]){
maxx=dis[j];
v=j;
}
}
vis[v]=1;
for(int j=1;j<=n;j++)
if(!vis[j] && f[v][j]>0 && dis[j]<dis[v]*f[v][j])
dis[j]=dis[v]*f[v][j];
}
}
int main(){
int x,y,z;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
f[x][y]=f[y][x]=1-z*1.0/100;
}
int s,e;
cin>>s>>e;
dijkstra(s);
printf("%.8f\n",100/dis[e]);
return 0;
}