POJ 3411 Paid Roads
题目大意:
给定n个点和m条边,每条边是点i到点j的单向边。当经过这条路前经过了点k,那么在经过这条路时付P的金钱,否则付R的金钱。
求点1到点n的最小花费是多少。
解题思路:
这个题可以用优先队列BFS。按照花费的高低排序。但是在BFS过程中不能当经过某一点时就判断他被访问过以后不再经过了。需要对每个点的访问的次数就行记录。超过这个次数就不再访问。其他的都很简单 。
下面是代码:
#include <stdio.h> #include <string.h> #include <queue> using namespace std; int head[11]; struct edge1 { int b,c,p,r,next; } edge[11]; int n,m,cnt; int num[11]; struct node { int pay,fa; bool vis[11]; bool operator < (const node &a) const { return a.pay<pay; } }; void addedge(int a,int b,int c,int p,int r) { edge[cnt].b=b; edge[cnt].c=c; edge[cnt].p=p; edge[cnt].r=r; edge[cnt].next=head[a]; head[a]=cnt++; } int main() { scanf("%d%d",&n,&m); int a,b,c,p,r; memset(head,-1,sizeof(head)); cnt=0; for(int i=0; i<m; i++) { scanf("%d%d%d%d%d",&a,&b,&c,&p,&r); addedge(a,b,c,p,r); } struct node temp,xtemp; memset(temp.vis,false,sizeof(temp.vis)); memset(num,0,sizeof(num)); temp.vis[1]=true; num[1]++; temp.pay=0; temp.fa=1; priority_queue <struct node> q; q.push(temp); while(!q.empty()) { temp=q.top(); if(temp.fa==n)break; q.pop(); if(num[temp.fa]>24)continue; int p=head[temp.fa]; while(p!=-1) { xtemp=temp; xtemp.vis[edge[p].b]=true; if(xtemp.vis[edge[p].c]) { xtemp.pay+=edge[p].p; } else xtemp.pay+=edge[p].r; xtemp.fa=edge[p].b; num[edge[p].b]++; q.push(xtemp); p=edge[p].next; } } if(temp.fa!=n)printf("impossible\n"); else printf("%d\n",temp.pay); return 0; }