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


posted @ 2014-04-09 20:22  、小呆  阅读(234)  评论(0编辑  收藏  举报