pku 3411 Paid Roads

搜的,刚才就是说的这题。

如果可以减少花费, 就要再次进队,不然就算了。

这题写的不是很好,有更好的实现方式的。

#include <iostream>
#include <bitset>
#include <iomanip>
#define N 11
#define MM 100000
#define MAX_LEN 1000

using namespace std;

struct TNode
{
	int b,r;
	int c,p;
	TNode *next;
	TNode(int bb,int cc,int pp, int rr):b(bb),r(rr),c(cc),p(pp),next(NULL){}
};

struct Node
{
	TNode *next;
	Node():next(NULL){}
};

Node adj[N];
int n;
inline void addEdge(int a,int b,int c,int p,int r)
{	
	TNode *t = new TNode(b,c,p,r);
	t->next = adj[a].next;
	adj[a].next = t;
}

int dest;
int cost[(1<<10)][10]={false};// cost[i][j] record cost to j in state i
struct QNode
{
	int path;
	int city;
	int cost;
};

QNode que[MAX_LEN];
int top,end;

inline int getBit(int a,int p)
{
	return ((a>>p)& 0x01);
}
inline int setBit(int a,int p)
{ 
	return (a|(1<<p));
}
void bfs()
{
	top = 0;
	end = 1;
	que[0].city = 0;
	que[0].path = 1;
	que[0].cost = 0;
	cost[1][0] = 0;

	QNode tmp;
	TNode * t;

	while (top != end)
	{
		tmp = que[top];
		++top;
		t = adj[tmp.city].next;
		while (t != NULL)
		{
			que[end].path = setBit(tmp.path,t->b);
			que[end].city = t->b;
			que[end].cost = tmp.cost + t->r;
			if (cost[que[end].path][que[end].city]==-1 || que[end].cost < cost[que[end].path][que[end].city])
			{
				cost[que[end].path][que[end].city] = que[end].cost;
				++end;
			}

			if (getBit(tmp.path,t->c) == 1) 
			{
				que[end].path = setBit(tmp.path,t->b);
				que[end].city = t->b;
				que[end].cost = tmp.cost + t->p;
				if (cost[que[end].path][que[end].city]==-1 || que[end].cost < cost[que[end].path][que[end].city])
				{
					cost[que[end].path][que[end].city] = que[end].cost;
					++end;
				}
			}
			t = t->next;
		}
	}
}

void output()
{
	int re = MM;
	for (int I=0; I< (1<<10); ++I)
	{
		if (cost[I][dest] >=0 && cost[I][dest]<re)
			re = cost[I][dest];
	}
	if (re == MM)
		cout<<"impossible"<<endl;
	else
		cout<<re<<endl;
}

int main()
{
	int a,b,c,p,r;
	cin>>dest>>n;
	--dest;
	for (int I=0; I<n; ++I)
	{
		cin>>a>>b>>c>>p>>r;
		--a; --b;--c;
		addEdge(a,b,c,p,r);
	}

	memset(cost, -1, sizeof(cost));
	bfs();
	output();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值