uva 11367 - Full Tank?(dijkstra TLE)

来源:互联网 发布:双代号网络计划计算 编辑:程序博客网 时间:2024/06/07 09:28

TLE 啊 TLE,我的想法和讨论版里的是一样的,为什么就是一直TLE呢。是每次查询都重做一遍dijkstra导致的吗?怎么还有人也那样却ac了呢。求大神解释啊。

代码啊,恶心的代码啊

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>//#include <map>using namespace std;const int maxn = 1000 + 5;const int maxN = 100000 + 5;const int INF = 1000000000;struct Edge{    int from,to,dist;    bool operator <(const Edge& rhs) const{        if(from < rhs.from || from == rhs.from && to < rhs.to ||           from == rhs.from && to == rhs.to && dist < rhs.dist)            return true;        return false;    }};struct Node{    int px,d;};struct Mark{    int n,c;}mark[maxN];//记录某个编号对应的状态struct Heapnode{//优先队列的结点    int d,u;    bool operator < (const Heapnode& rhs) const{        return d > rhs.d;    }};struct Dijkstra{    int n,m;//原始点数和边数    vector<Edge> edges;//边列表    vector<int> G[maxN];//每个节点出发的边编号(从0开始)    bool done[maxN];//是否已永久编号    int d[maxN];//s到各个点的距离    vector<Node> match[maxn];//初始图中每个点相邻的那条边    int price[maxn];    int id[maxn][105];//某个状态对应的编号    int Count;   // map<Edge,int> M;    void init(int n){        this -> n = n;        for(int i = 0;i < maxN;i++) G[i].clear();//清空邻接表        edges.clear();//清空边表        //M.clear();        Count = 0;        for(int i = 0;i < maxn;i++)            for(int j = 0;j < 105;j++){                id[i][j] = -1;            }    }    void AddEdge(int from,int to,int dist){        //printf("1. %d-%d  %d\n",from,to,dist);        //如果是无向图,每条无向边需调用两次AddEdge        /*if(M.count((Edge){from,to,dist}) != 0)            return;*/        //printf("2. %d-%d  %d\n",from,to,dist);        edges.push_back((Edge){from,to,dist});        //M[(Edge){from,to,dist}] = 1;        m = edges.size();        G[from].push_back(m-1);//(m-1)因为边从0开始编号    }    int ID(int n,int c){        int x = id[n][c];        if(x == -1){            x = Count++;            id[n][c] = x;            mark[x].n = n;            mark[x].c = c;        }        return x;    }    void dijkstra(int s,int c){//求s到所有点的距离        priority_queue<Heapnode> Q;        for(int i = 0;i < maxN;i++)    d[i] = INF;        d[s] = 0;        memset(done,0,sizeof(done));        Q.push((Heapnode){0,s});        while(!Q.empty()){            Heapnode x = Q.top();Q.pop();            int u = x.u;//u是这个节点的编号            if(done[u]) continue;            done[u] = true;            int minp = INF;//记录在这个点最小的c            int temn = mark[u].n;//当前节点的原图中位置            int temc = mark[u].c;//当前节点的c值            //走向其他点的边            for(int i = 0;i < match[temn].size();i++){                int temp = match[temn][i].px;//相邻点在原图中的位置                int temd = match[temn][i].d;//相邻边的距离                minp = min(minp,temd);                if(temc >= temd){                    AddEdge(u,ID(temp,temc-temd),0);                    //printf("%d-%d   %d-%d\n",temn,temc,temp,temc-temd);                }            }            //加油的边            for(int i = max(1,minp-temc);i <= c-temc;i++){                AddEdge(u,ID(temn,temc+i),price[temn]*i);            }            for(int i = 0;i < G[u].size();i++){                Edge& e = edges[G[u][i]];                if(d[e.to] > d[u] + e.dist){                    d[e.to] = d[u] + e.dist;                    Q.push((Heapnode){d[e.to],e.to});                }            }        }    }};Dijkstra solver;int main(){    int n,m,u,v,d;    while(scanf("%d%d",&n,&m) != EOF){        for(int i = 0;i < n;i++) solver.match[i].clear();        for(int i = 0;i < n;i++)            scanf("%d",&solver.price[i]);        while(m--){            scanf("%d%d%d",&u,&v,&d);            solver.match[u].push_back((Node){v,d});            solver.match[v].push_back((Node){u,d});        }        int q,c,s,t;        scanf("%d",&q);        while(q--){            scanf("%d%d%d",&c,&s,&t);            if(t < s)   swap(s,t);            solver.init(n);            solver.dijkstra(solver.ID(s,0),c);            int ans = INF;            for(int i = 0;i <= c;i++){                ans = min(ans,solver.d[solver.ID(t,i)]);            }            //for(int i = 0;i < solver.Count;i++)                //printf("%d ",solver.d[i]);            if(ans == INF)                printf("impossible\n");            else                printf("%d\n",ans);        }    }    return 0;}


 

原创粉丝点击