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