您的位置:首页 > 大数据 > 人工智能

poj3411Paid Roads(bfs+状态压缩)

2014-11-17 16:51 211 查看
题目链接:http://poj.org/problem?id=3411

题意:给一个有向图,从一个点a到达另一个点b,如果之前经过c,则花费为c1,否则花费为c2.

题目解析:此图是一个有向图,每个点可以走多次,将一个点的多个状态进行压缩保存,放入队列。

代码如下:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N=(1<<10)+8;     //每个顶点都有1<<10+8个状态
const int M=14;
const int INF=0x3f3f3f3f;
int vis[M][N];
int m,n;
struct n
{
int c1,c2;
}map[M][M][M];
struct node
{
int cur;         //当前节点的标号
int cost;       //花费
int key;         //状态
}n1,n2;
int bfs()
{
int ans=INF;
queue<node>q;
n1.cur=0;   //将节点的标号从0开始
n1.cost=0;
n1.key=1;
q.push(n1);
vis[0][1]=0;      //用来记录到达某个顶点某种状态的最小价值
while(!q.empty())
{
n2=q.front();
q.pop();
if(n2.key&(1<<(m-1)))    ans=min(ans,n2.cost);
for(int i=0;i<m;i++)
for(int j=0;j<m;j++)
{
if(map[n2.cur][i][j].c1!=-1)
{
int csa=INF;
int csb=INF;
if(n2.key&(1<<j))   //之前经过此点
csa=n2.cost+map[n2.cur][i][j].c1;
csb=n2.cost+map[n2.cur][i][j].c2;
n1.cost=min(csa,csb);
n1.cur=i;
n1.key=n2.key;
if(!(n1.key&(1<<i)))
n1.key|=(1<<i);
if(n1.cost<vis[i][n1.key])
{
vis[i][n1.key]=n1.cost;
q.push(n1);
}
}
}
}
return ans;

}
int main()
{
int a,b,c,c1,c2;
while(scanf("%d%d",&m,&n)!=EOF)
{
for(int i=0;i<(1<<m);i++)
for(int j=0;j<m;j++)
vis[j][i]=INF;
memset(map,-1,sizeof(map));
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d%d",&a,&b,&c,&c1,&c2);
a-=1;
b-=1;
c-=1;
if(map[a][b][c].c1!=-1)
map[a][b][c].c1=min(map[a][b][c].c1,c1);
else
map[a][b][c].c1=c1;
if(map[a][b][c].c2!=-1)
map[a][b][c].c2=min(map[a][b][c].c2,c2);
else
map[a][b][c].c2=c2;
}
int as=bfs();
if(as!=INF)  printf("%d\n",as);
else  printf("impossible\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: