intさわだんのBlack History

刹那的レジェンドになりたい。

ICPC 離散的速度 AOJ1162

多少工夫してみたがMLEが取れないため保留
問題自体は解けたため次に進む

#include <bits/stdc++.h>
#define chmin(a, b) ((a)=min((a), (b)))
#define chmax(a, b) ((a)=max((a), (b)))
#define fs first
#define sc second
#define eb emplace_back
using namespace std;
  
typedef long long ll;
typedef pair<int, int> P;
typedef tuple<double, int, int, int> T;
  
const ll MOD=1e9+7;
//const ll INF=1e18;
 
const double INF = 1000000.0;
  
int dx[]={0, 1, 0, -1};
int dy[]={-1, 0, 1, 0};
 
struct edge{ int to,d,c;};
 
 
 
int n,m,s,g;
double d[35][35][35];
double mind;
 
int main(){
    while(true){
        cin >> n >> m;
        if(n + m == 0) break;
        cin >> s >> g;
        mind = INF;
        vector<edge> G[35];
        for(int i = 0;i < m;i++){
            int a1,a2,a3,a4;
            cin >> a1 >> a2 >> a3 >> a4;
            edge tmp1 = {a2,a3,a4};
            G[a1].push_back(tmp1);
            edge tmp2 = {a1,a3,a4};
            G[a2].push_back(tmp2);
        }
        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= n;j++){
                for(int k = 0;k <= 31;k++){
                    d[i][j][k] = INF;
                }
            }
        }
		priority_queue<T,vector<T>,greater<T> > que2;
        for(int i = 0;i < G[s].size();i++){
            edge e = G[s][i];
            d[s][e.to][1] = (double) e.d;
            que2.push(make_tuple((double)e.d,1,s,e.to));
        }
        while(!que2.empty()){
            T t = que2.top(); que2.pop();
            double a1 = get<0>(t);
            int a2 = get<1>(t),a3 = get<2>(t),a4 = get<3>(t);
            if(d[a3][a4][a2] < a1 || a1 > mind)continue;
            for(int i = 0;i < G[a4].size();i++){
                edge e = G[a4][i];
                if(e.to == a3) continue;
                double tmp = (double) a1 + (double)e.d;
                if(d[a4][e.to][1] < tmp)continue;
                d[a4][e.to][1] =  tmp;
                if(mind < tmp) continue;
                if(e.to == g && mind > tmp)mind = tmp;
                que2.push(make_tuple(tmp,1,a4,e.to));
            }
        }
        if(mind == INF){
            cout << "unreachable" << endl;
            continue;
        }
        //queue<T> que;
        //priority_queue<T,vector<T>,greater<T> > que;
		priority_queue<T> que;
        for(int i = 0;i < G[s].size();i++){
            edge e = G[s][i];
            d[s][e.to][1] = (double) e.d;
            que.push(make_tuple((double)e.d,1,s,e.to));
        }
        while(!que.empty()){
            //T t = que.front(); que.pop();
            T t = que.top(); que.pop();
            double a1 = get<0>(t);
            int a2 = get<1>(t),a3 = get<2>(t),a4 = get<3>(t);
            if(d[a3][a4][a2] < a1 || a1 > mind)continue;
            for(int i = 0;i < G[a4].size();i++){
                edge e = G[a4][i];
                if(e.to == a3) continue;
                for(int j = -1;j <= 1;j++){
                    int v = a2 + j;
                    double tmp = (double)( a1 + (double)e.d / (double)v);
            //      if(a4 == 5 && e.to == 6 && v == 1) cout << "tmp" << tmp << ",a1" << a1 <<endl;
                    if(v <= 0 || v > e.c || d[a4][e.to][v] < tmp ||tmp > mind) continue;
                    d[a4][e.to][v] =  tmp;
                    if(e.to == g && v == 1 && mind > tmp)mind = tmp;
                    que.push(make_tuple(tmp,v,a4,e.to));
                }
            }
         
         
        }
    //  cout << "ans" << d[4][5][2] << endl;
 
 
 
        double ans = INF;
        for(int i = 1;i <= n;i++){
            double tmp = d[i][g][1];
            if(ans > tmp) ans = tmp;
        //  ans = min(ans,d[i][g][1]);
        }
        if(ans == INF){
            cout << "unreachable" << endl;
        }else{
        //  cout << ans << endl;
            printf("%lf\n",ans);
        }
    }
}
#include <bits/stdc++.h>
#define chmin(a, b) ((a)=min((a), (b)))
#define chmax(a, b) ((a)=max((a), (b)))
#define fs first
#define sc second
#define eb emplace_back
using namespace std;
  
typedef long long ll;
typedef pair<int, int> P;
typedef tuple<double, int, int, int> T;
  
const ll MOD=1e9+7;
//const ll INF=1e18;
 
const double INF = 1000000.0;
  
int dx[]={0, 1, 0, -1};
int dy[]={-1, 0, 1, 0};
 
struct edge{ int to,d,c;};
 
 
 
int n,m,s,g;
double d[35][35][35];
double mind;
 
int main(){
    while(true){
        cin >> n >> m;
        if(n + m == 0) break;
        cin >> s >> g;
        mind = INF;
        vector<edge> G[35];
        for(int i = 0;i < m;i++){
            int a1,a2,a3,a4;
            cin >> a1 >> a2 >> a3 >> a4;
            edge tmp1 = {a2,a3,a4};
            G[a1].push_back(tmp1);
            edge tmp2 = {a1,a3,a4};
            G[a2].push_back(tmp2);
        }
        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= n;j++){
                for(int k = 0;k <= 31;k++){
                    d[i][j][k] = INF;
                }
            }
        }
        //queue<T> que;
        priority_queue<T,vector<T>,greater<T> > que;
        for(int i = 0;i < G[s].size();i++){
            edge e = G[s][i];
            d[s][e.to][1] = (double) e.d;
            que.push(make_tuple((double)e.d,1,s,e.to));
        }
        while(!que.empty()){
            //T t = que.front(); que.pop();
            T t = que.top(); que.pop();
            double a1 = get<0>(t);
            int a2 = get<1>(t),a3 = get<2>(t),a4 = get<3>(t);
            if(d[a3][a4][a2] < a1 || a1 > mind)continue;
            for(int i = 0;i < G[a4].size();i++){
                edge e = G[a4][i];
                if(e.to == a3) continue;
                for(int j = -1;j <= 1;j++){
                    int v = a2 + j;
                    double tmp = (double)( a1 + (double)e.d / (double)v);
            //      if(a4 == 5 && e.to == 6 && v == 1) cout << "tmp" << tmp << ",a1" << a1 <<endl;
                    if(v <= 0 || v > e.c || d[a4][e.to][v] < tmp ||tmp > mind) continue;
                    d[a4][e.to][v] =  tmp;
                    if(e.to == g && v == 1 && mind > tmp)mind = tmp;
                    que.push(make_tuple(tmp,v,a4,e.to));
                }
            }
         
         
        }
    //  cout << "ans" << d[4][5][2] << endl;
 
 
 
        double ans = INF;
        for(int i = 1;i <= n;i++){
            double tmp = d[i][g][1];
            if(ans > tmp) ans = tmp;
        //  ans = min(ans,d[i][g][1]);
        }
        if(ans == INF){
            cout << "unreachable" << endl;
        }else{
        //  cout << ans << endl;
            printf("%lf",ans);
        }
    }
}