很经典的最短路问题。
只需修改一下松弛方程就可以。比赛的时候被北京某年Regional的一道题误导了,开始没敢做,后来发现被群A后才做的。。o(╯□╰)o
松弛方程修改如下:
int relax(int u,int v,double c){ if(dist[v] > dist[u]+(M-dist[u])*((double)c/100.0)){ dist[v] = dist[u]+(M-dist[u])*(c/100.0); return 1; } return 0; }
附AC代码:
View Code
#include <iostream> #include <string.h> #include <stdio.h> #include <queue> using namespace std; #define swap(t,a,b) (t=a,a=b,b=t) const int INF = 0x3F3F3F3F; const int V = 50005; const int E = 2505010; int pnt[E],nxt[E]; int e,head[V]; double dist[V],cost[E],M; bool vis[V]; int cnt[V]; int relax(int u,int v,double c){ if(dist[v] > dist[u]+(M-dist[u])*((double)c/100.0)){ dist[v] = dist[u]+(M-dist[u])*(c/100.0); return 1; } return 0; } inline void addedge(int u,int v,double c){ //cout <<c<<endl; pnt[e]=v; cost[e]=c; nxt[e]=head[u]; head[u]=e++; } void spfa(int src,int n){ int i; memset(cnt,0,sizeof(cnt)); memset(vis,false,sizeof(vis)); for(i=1;i<=n;i++) dist[i]=INF; dist[src]=0; queue<int> Q; Q.push(src); vis[src]=true; ++cnt[src]; while(!Q.empty()){ int u,v; u=Q.front(); Q.pop(); vis[u]=false; for(i=head[u];i!=-1;i=nxt[i]){ v=pnt[i]; if(1==relax(u,v,cost[i]) && !vis[v]){ Q.push(v); vis[v]=true; //if((++cnt[v])>n) return -1; } } } //if(dist[n]==INF) return -2; return ; } int main(){ //freopen("in.txt","r",stdin); int n,m,b,d,s,t; while(scanf("%d",&n)!=EOF){ e=0; memset(head,-1,sizeof(head)); for(int i=1;i<=n;i++){ scanf("%d",&m); while(m--){ scanf("%d%d",&b,&d); addedge(i,b,d); } } scanf("%d%d%lf",&s,&t,&M); spfa(s,n); if(M-dist[t]>0) printf("%.2lf\n",dist[t]); else printf("IMPOSSIBLE!\n"); } return 0; }