很经典的最短路问题。

只需修改一下松弛方程就可以。比赛的时候被北京某年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;
}