简单的一题,使用类DIJK的算法就可以了。
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> using namespace std; struct Edge{ int u,v; double lose; int next; }edge[2500050]; int head[50010]; bool vis[50010]; int tot; void addedge(int u,int v,double l){ edge[tot].u=u; edge[tot].v=v; edge[tot].lose=l; edge[tot].next=head[u]; head[u]=tot++; } double dist[50010]; struct point{ int node; double power; bool operator < (const point &p)const { return power<p.power; } }pushed,tmp; priority_queue<point>que; int main(){ int n,v,l,f,t; double M; while(scanf("%d",&n)!=EOF){ int k; tot=0; for(int i=1;i<=n;i++){ head[i]=-1; vis[i]=false; dist[i]=0; } for(int u=1;u<=n;u++){ scanf("%d",&k); for(int p=1;p<=k;p++){ scanf("%d%d",&v,&l); addedge(u,v,l*1.0); } } scanf("%d%d%lf",&f,&t,&M); tmp.node=f; tmp.power=M; dist[f]=M; que.push(tmp); while(!que.empty()){ tmp=que.top(); if(tmp.node==t) break; que.pop(); if(vis[tmp.node]) continue; vis[tmp.node]=true; for(int e=head[tmp.node];e!=-1;e=edge[e].next){ if(!vis[edge[e].v]){ if(tmp.power*(1-edge[e].lose*1.0/100)>dist[edge[e].v]){ dist[edge[e].v]=tmp.power*(1-edge[e].lose*1.0/100); pushed.node=edge[e].v; pushed.power=dist[edge[e].v]; que.push(pushed); } } } } if(dist[t]<1e-8) printf("IMPOSSIBLE! "); else printf("%.2lf ",M-dist[t]); while(!que.empty()) que.pop(); } return 0; }