本题不难,可是笔者贡献了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); }