本題不難,可是筆者貢獻了30屢次Submit……就像Discuss討論的同樣,細節決定成敗,WA了確定有理由。spa
貼代碼,Dijkstra+優先隊列。code
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn = 101; int first[maxn],vv[maxn*maxn],nxt[maxn*maxn],ww[maxn*maxn]; int vis[maxn],level[maxn],price[maxn]; int Min=~(1<<31); struct Node { int k,w; bool operator<(const Node& cmp) const { return w>cmp.w; } } p,q; void Dijkstra() { p.k=1; p.w=0; priority_queue<Node> pq; pq.push(p); while(!pq.empty()) { p=pq.top(); pq.pop(); vis[p.k]=true; Min=min(Min,p.w+price[p.k]); for(int e=first[p.k]; e; e=nxt[e]) if(!vis[vv[e]]) { q.k=vv[e]; q.w=p.w+ww[e]; pq.push(q); } } } int main() { // freopen("in.txt","r",stdin); int e=2; int M,n; scanf("%d%d",&M,&n); for(int i=1; i<=n; i++) { int swap; scanf("%d%d%d",price+i,level+i,&swap); for(int j=0; j<swap; j++) { int v,w; scanf("%d%d",&v,&w); nxt[e]=first[i],vv[e]=v,ww[e]=w,first[i]=e++; } } for(int l=level[1]-M; l<=level[1]; l++) { for(int i=1; i<=n; i++) if(level[i]<l || level[i]>l+M) vis[i]=true; else vis[i]=false; Dijkstra(); } printf("%d\n",Min); }