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; }