Why is this code inefficient?

Asked 2 years ago, Updated 2 years ago, 46 views

F-I challenged the snake JOI-kun, but it became TLE.
But I don't understand why my code is inefficient.Could you please let me know the problem with the code?Below is my code.

int N, M, X, T[10000];

structedge {
    int to, cost;
};

structure situ {
    int cost, v, dist, type;

    bool operator<(const situ&rhs)const
    {
        return cost<rhs.cost;
    }
};

vector<edge>G[10005];

intd[10005][205][3];

void dijkstra(ints) {

    d[0][0][0]=0;
    priority_queue<situ>queue;
    queue.push({0,s,0,0});
    while(!que.empty()){
        situp=queue.top();queue.pop();
        int cost = p.cost, v = p.v;
        if(d[v][p.dist][p.type]<cost)continue;
        for (edge u:G[v]) {

            if(abs(p.type-T[u.to])>1&p.dist+u.cost<X){
                continue;
            }
            int type=p.type, dist=min(p.dist+u.cost,X);
            if(T[u.to]!=1){
                type = T [u.to];
                dist = 0;
            }

            if(d[u.to][dist][type]>d[v][p.dist][p.type]+u.cost){
                d[u.to][dist][type]=d[v][p.dist][p.type]+u.cost;
                queue.push ({d[u.to][dist][type], u.to, dist, type});

            }
        }
    }
}
int main()
{
    cin>>N>>M>X;
    rep(i,N){
        cin>>T[i];
    }
    rep(i,M){
        int a, b, d;
        cin>>a>>b>d;
        a--;b--;
        G[a].push_back({b,d});
        G[b].push_back({a,d});
    }
    rep(i,N){
        rep(j,X+1){
            fill_n(d[i][j],3,INF);
        }
    }
    dijkstra(0);
    N--;
    intans=INF;
    rep(i,X+1){
        rep(j,3){
            an=min(ans,d[N][i][j]);
        }
    }
    cout<ans<<endl;

}

Next is the sample code

#include<cstdio>
# include <vector>
# include <utility>
# include <queue>

using namespace std;

constint MAX_N = 10000;
constint MAX_X = 200;

const int inf = 1e9;
    US>structure Edge {
        int to, cost;
        Edge(){}
        Edge(int to, int cost):to(to), cost(cost){}
    };

    vector<Edge>G[MAX_N];
    int color [MAX_N]; // temperature (0/1/2)

    int N, X;

    intdis[MAX_N][2][MAX_X+1];

    typeef pair<int,int>P;//<temperature of the neighbor non-comfortable room (0 or 2), distance from there>
    typeef pair<int,P>P2;//<vertex,P>
    typeef pair <int, P2>P3;//<distance from, P2>

    Update_state(Pp,Edgee){
        if(color[e.to]==0){
            if(p.first==2&p.second+e.cost<X){
                return P(-1,-1);
            } else {
                return P(0,0);
            }
        } else if(color[e.to]==1){
            int d = min(X, p.second + e.cost);
            return P(p.first,d);
        } else {
            if(p.first==0&p.second+e.cost<X){
                return P(-1,-1);
            } else {
                return P(2,0);
            }
        }
    }

    void dijkstra() {
        priority_queue<P3, vector<P3>, greater<P3>queue;
        for(inti=0;i<N;++i){
            for(int j=0;j<3;++j){
                for(intk=0;k<MAX_X+1;++k){
                    dis[i][j][k]=inf;
                }
            }
        }

        dis[0][0][0]=0;
        queue.push(P3(0,P2(0,P(0,0)));

        while(!que.empty()){
            P3 p3 = queue.top();
            queue.pop();
            intd = p3.first;
            intv = p3.second.first;
            Pprv_state = p3.second.second;
            if(dis[v][prv_state.first/2][prv_state.second]<d)continue;
            for(inti=0;i<G[v].size();++i){
                Pnp = update_state(prv_state, G[v][i]);
                if(np==P(-1,-1) continue;
                intnd=d+G[v][i].cost;
                int nv = G[v][i].to;
                if(dis[nv][np.first/2][np.second]<=nd)continue;
                dis[nv][np.first/2][np.second]=nd;
                queue.push(P3(nd,P2(nv,np)));
            }
        }
    }

    int solve(){
        dijkstra();
        intans=inf;
        for(intc=0;c<2;++c){
            for(intd=0;d<=X;++d){
                an=min(ans,dis[N-1][c][d]);
            }
        }
        for(intv=0;v<N;++v){
            int tmp = inf;
            for(intc=0;c<2;++c){
                for(intd=0;d<=X;++d){
                    tmp = min(tmp,dis[v][c][d]);
                }
            }
        }
        returnans;
    }

    void input() {
        int M;
        scanf("%d%d%d", & N, & M, & X);
        for(inti=0;i<N;++i){
            scanf("%d", color+i);
        }
        for(inti=0;i<M;++i){
            intu, v, d;
            scanf("%d%d%d", &u, &v, &d);
            u--;
            v--;
            G[u].push_back(Edge(v,d));
            G[v].push_back(Edge(u,d));
        }
    }

    int main() {
        input();
        intans=solve();
        printf("%d\n",ans);
        return 0;
    }

By the way, the sample code is 60 ms at worst.
Restrictions are listed at the first URL.
Note:
This is the abbreviated part of my code

#define_USE_MATH_DEFINES
# include <math.h>

// # include <cmath>

# include <deque>
# include <queue>
# include <vector>
# include <algorithm>
# include <iostream>
# include <set >
# include <cmath>
# include <tuple>
# include <string>
# include <chrono>
# include <functional>
# include <iterator>
# include <random>
# include <unordered_set>
# include <array>
# include <map>
# include <iomanip>
# include <assert.h>
# include <bitset>
# include <stack>
# include <memory>



// # include "Ants.h"
using namespace std;
typeedef long long ll;
#define rad_to_deg(rad)((rad)/2/M_PI)*360)
# define EPS (1e-7)
#define INF(1e9)
#definePI(acos(-1))
# define rep(i,n) for (inti=0;i<n;i++)
# define show(s) cout<<s<endl
# define chmin(x,y)x = min(x,y)
# define chmax(x,y)x = max(x,y)
# define LINF (10000000000000000000000ll)
typeef pair <int,int>P;

c++ algorithm

2022-09-29 22:32

2 Answers

I am writing to inform you that I understand the cause of the questioner.In conclusion, there is probably no problem with the code itself (dijkstra and main function part).However, it seems that the operator< sign on the structure situ was in the opposite direction.I have made other minor changes, so I will put the code on it just in case.

#define_USE_MATH_DEFINES
# include <math.h>

// # include <cmath>

# include <deque>
# include <queue>
# include <vector>
# include <algorithm>
# include <iostream>
# include <set >
# include <cmath>
# include <tuple>
# include <string>
# include <chrono>
# include <functional>
# include <iterator>
# include <random>
# include <unordered_set>
# include <array>
# include <map>
# include <iomanip>
# include <assert.h>
# include <bitset>
# include <stack>
# include <memory>



// # include "Ants.h"
using namespace std;
typeedef long long ll;
#define rad_to_deg(rad)((rad)/2/M_PI)*360)
# define EPS (1e-7)
#define INF(1e9)
#definePI(acos(-1))
# define rep(i,n) for (inti=0;i<n;i++)
# define show(s) cout<<s<endl
# define chmin(x,y)x = min(x,y)
# define chmax(x,y)x = max(x,y)
# define LINF (10000000000000000000000ll)
typeef pair <int,int>P;

int N, M, X, T[10000];

structedge {
    int to, cost;
};

structure situ {
    int cost, v, dist, type;

    bool operator<(const situ&rhs)const
    {
        if(cost==rhs.cost){
            return dist <rhs.dist;
        }
        return cost>rhs.cost;
    }
};

vector<edge>G[10005];

intd[10005][205][3];

void dijkstra(ints) {

    priority_queue<situ>queue;
    queue.push({0,s,0,0});
    while(!que.empty()){
        situp=queue.top();queue.pop();
        int cost = p.cost, v = p.v;
        if(d[v][p.dist][p.type]<cost)continue;

        // cout<<<cost<"<v<<"<<p.type<<"<p.dist<<endl;
        //cout<<queue.top().cost<<endl;
        for (edge u:G[v]) {

            if(abs(p.type-T[u.to])>1&p.dist+u.cost<X){
                continue;
            }
            int type=p.type, dist=min(p.dist+u.cost,X);
            if(T[u.to]!=1){
                type = T [u.to];
                dist = 0;
            }

            if(d[u.to][dist][type]>d[v][p.dist][p.type]+u.cost){
                d[u.to][dist][type]=d[v][p.dist][p.type]+u.cost;
                for(intx=dist;x>=0;--x){
                    d[u.to][x][type]=min(d[u.to][x][type], d[u.to][dist][type]);
                }
                queue.push ({d[u.to][dist][type], u.to, dist, type});

            }
        }
    }
}
int main()
{
    cin>>N>>M>X;
    rep(i,N){
        cin>>T[i];
    }
    rep(i,M){
        int a, b, d;
        cin>>a>>b>d;
        a--;b--;
        G[a].push_back({b,d});
        G[b].push_back({a,d});
    }
    rep(i,N){
        rep(j,X+1){
            fill_n(d[i+1][j],3,INF);
        }
    }
    dijkstra(0);
    N--;
    intans=INF;
    rep(i,X+1){
        rep(j,3){
            an=min(ans,d[N][i][j]);
        }
    }
    cout<ans<<endl;

}

The main issue has been resolved, but I have one question: the direction of the operator< sign.
If I remember correctly, I made a function cmp to sort the sort function {sort(begin, end, cmp)} in ascending order with structure, but I remember that the direction of the sign was '<'. Why is it '>'?I would appreciate it if you could let me know.
Note: The worst run time was 53 ms.It seems to be almost the same as the sample.


2022-09-29 22:32

Have you read the problem commentary website?
https://www.ioi-jp.org/joi/2016/2017-yo/2017-yo-t6/review/2017-yo-t6-review.html

First of all, the questioner's program is not a Dijkstra method.
Check and calculate all available room information for one room taken out in while
We put the most efficient routes in the queue, but it's not much different from calculating all routes recursively.

First, practice writing the logic of calculating using the Dijkstra method.
In the Dijkstra method, the shortest distance to the next room is
from the array holding the shortest distance to the previous room. It's an algorithm that doesn't make useless calculations by calculating.


2022-09-29 22:32

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.