poj 3635 带花费的Dij+head优化
练习!!
这里主要需要注意的是进队的条件和dp[][]状态的控制,dp[i][j]表示到第i个城市剩余汽油为j的最小花费。
代码:
#include<iostream> #include<queue> #include<cstdio> #include<cstring> #define inf 100000000 #define MAXN 1200 #define MAXM 1200 using namespace std; int head[MAXN],price[MAXN],dp[MAXN][120],vis[MAXN][120]; int temp,n,m; struct Node{ int v,len,next; }edge[2*MAXN*10]; struct Node1{ int d; int u; int cost; Node1(int x,int y,int z) { u=x; d=y; cost=z; } friend bool operator < (Node1 a,Node1 b) { return a.cost>b.cost; } }; void addEdge(int x ,int y ,int c) { edge[temp].v=x; edge[temp].len=c; edge[temp].next=head[y]; head[y]=temp; temp++; edge[temp].v=y; edge[temp].len=c; edge[temp].next=head[x]; head[x]=temp; temp++; } priority_queue<Node1> que; int Dijstra(int s,int t,int c) { while(!que.empty())que.pop(); for(int i=0;i<=n;i++) { for(int j=0;j<=c;j++) { dp[i][j]=inf; } } memset(vis,0,sizeof(vis)); dp[s][0]=0; que.push(Node1(s,0,0)); while(!que.empty()) { Node1 b=que.top(); que.pop(); int u=b.u; int d=b.d; int cost=b.cost; vis[u][d]=1; if(u==t) return cost; if(d+1<=c&&!vis[u][d+1]&&dp[u][d+1]>dp[u][d]+price[u]) { dp[u][d+1]=dp[u][d]+price[u]; que.push(Node1(u,d+1,dp[u][d+1])); } for(int i=head[u];i!=-1;i=edge[i].next) { int v; v=edge[i].v; int len=edge[i].len; if(d>=len&&!vis[v][d-len]&&dp[v][d-len]>cost) { dp[v][d-len]=cost; que.push(Node1(v,d-len,cost)); } } } return -1; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<n;i++) { scanf("%d",&price[i]); } memset(head,-1,sizeof(head)); temp=0; for(int i=1;i<=m;i++) { int v,w,c; scanf("%d%d%d",&v,&w,&c); addEdge(v,w,c); } int q; scanf("%d",&q); while(q--) { int q1,q2,q3; scanf("%d%d%d",&q1,&q2,&q3); int ans=Dijstra(q2,q3,q1); if(ans!=-1) { printf("%d\n",ans); } else printf("impossible\n"); } } return 0; }