洛谷 1576 最小花费

【题解】

  用最短路算法求A到B被扣除的最小百分比即可。稍微修改一下最短路的更新方式即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #define LL long long
 6 #define rg register
 7 #define N 2010
 8 #define M 100010
 9 using namespace std;
10 int n,m,tot,last[N],pos[N],from[N],rec[N][N];
11 double dis[N],ans=1;
12 struct edge{
13     int to,pre; double dis;
14 }e[M<<1];
15 struct heap{
16     int poi; double dis;
17 }h[N];
18 inline int read(){
19     int k=0,f=1; char c=getchar();
20     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
21     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
22     return k*f;
23 }
24 inline void up(int x){
25     int fa;
26     while((fa=(x>>1))&&h[fa].dis>h[x].dis){
27         swap(h[x],h[fa]),swap(pos[h[x].poi],pos[h[fa].poi]);
28         x=fa;
29     }
30 }
31 inline void down(int x){
32     int son;
33     while((son=x<<1)<=tot){
34         if(son<tot&&h[son].dis>h[son+1].dis) son++;
35         if(h[son].dis<h[x].dis){
36             swap(h[x],h[son]); swap(pos[h[x].poi],pos[h[son].poi]);
37             x=son;
38         }
39         else return;
40     }
41 }
42 inline void dijkstra(int x){
43     for(rg int i=1;i<=n;i++) dis[i]=1000000;
44     h[tot=pos[x]=1]=(heap){x,dis[x]=0};
45     while(tot){
46         int now=h[1].poi; h[1]=h[tot--]; if(tot) down(1);
47         for(rg int i=last[now],to;i;i=e[i].pre)
48         if(dis[to=e[i].to]>dis[now]+(1-dis[now])*e[i].dis){
49             dis[to]=dis[now]+(1-dis[now])*e[i].dis;
50             from[to]=now;
51             if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]};
52             else h[pos[to]].dis=dis[to];
53             up(pos[to]);
54         }
55         pos[now]=0;
56     }
57 }
58 int main(){
59     n=read(); m=read();
60     for(rg int i=1;i<=m;i++){
61         int u=read(),v=read(),d=rec[u][v]=rec[v][u]=read();
62         e[++tot]=(edge){v,last[u],d*1.0/100}; last[u]=tot;
63         e[++tot]=(edge){u,last[v],d*1.0/100}; last[v]=tot;
64     }
65     int s=read(),t=read();
66     dijkstra(s);
67     int last=from[t];
68     while(last){
69         ans*=(1-rec[last][t]*1.0/100);
70         t=last; last=from[t];
71 //        printf("%.8f\n",100*1.0/ans);
72     }
73     printf("%.8f\n",100*1.0/ans);
74     return 0;
75 }
View Code

dijkstra的更新方式可以改为dis[to]=dis[now]+(1-dis[now])*e[i].dis.

  

猜你喜欢

转载自www.cnblogs.com/DriverLao/p/9348229.html