POJ 3411 BFS+状压

来源:互联网 发布:淘宝非法交易如何退货 编辑:程序博客网 时间:2024/05/22 06:35

有n座城市和m(1<=n,m<=10)条路。现在要从城市1到城市n。有些路是要收费的,从a城市到b城市,如果之前到过c城市,那么只要付P的钱,如果没有去过就付R的钱。求的是最少要花多少钱。

注意:路径是有向的

状压存储已经到过的节点

hash[data.status][i]  记录以i为最后节点,走过节点为status,是否可行


#include "stdio.h"#include "string.h"#include "math.h"#include "queue"using namespace std;int b[]={0,1,2,4,8,16,32,64,128,256,512,1024};struct comp{    int x1,x2,c;}map[11][11];struct node{    int x;    int step;    int status;    friend bool operator<(node a1,node a2)    {        return a1.step>a2.step;    }};int hash[1<<11][11];int aim,ans,n;void bfs(){    node cur,next;    priority_queue<node>q;    int i;    cur.status=1;    cur.x=1;    cur.step=0;    q.push(cur);    memset(hash,0,sizeof(hash));    while (!q.empty())    {        cur=q.top();        q.pop();        if (cur.x==n) {ans=cur.step; return;}        if (hash[cur.status][cur.x]==1) continue;        hash[cur.status][cur.x]=1;        for (i=1;i<=n;i++)        {            if (map[cur.x][i].x1!=-1 && (map[cur.x][i].c & cur.status)== map[cur.x][i].c)            {                next.step=cur.step+map[cur.x][i].x1;                next.status=cur.status | b[i];                next.x=i;                q.push(next);            }            else            if (map[cur.x][i].x2!=-1)            {                next.step=cur.step+map[cur.x][i].x2;                next.status=cur.status | b[i];                next.x=i;                q.push(next);            }        }    }}int main(){    int a,b,c,p,r,m;    while (scanf("%d%d",&n,&m)!=EOF)    {        ans=-1;        aim=(1<<(n))-1;        memset(map,-1,sizeof(map));        while (m--)        {            scanf("%d%d%d%d%d",&a,&b,&c,&p,&r);            map[a][b].x1=p;            map[a][b].x2=r;            map[a][b].c=c;        }        bfs();        if (ans==-1) printf("impossible\n");        else printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击