BZOJ1975: [Sdoi2010]魔法猪学院

1 篇文章 0 订阅

第一道A*。。。

今天才会做k短路。。。。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
struct Node
{
	int x;
	double dis;
	inline friend bool operator<(Node a,Node b){return a.dis>b.dis;	}
};
struct node
{
	double f,g;
	int v;
	inline friend bool operator<(node a,node b){return a.f>b.f;	}
};

priority_queue<Node> Q;
struct Chain
{int other;double len;Chain*next;Chain(){next=NULL;}}*Head[10001],*OP_Head[10001];
double Dis_To[5001];
const int INF=1<<29;
int n;
inline void dij(int start)
{
	while(!Q.empty())
	Q.pop();
	Q.push((Node){start,0});
	Node tp;
	int i;
	for(i=1;i<=n;i++)
	  Dis_To[i]=INF;
	while(true)
	{
	    while(Dis_To[Q.top().x]!=INF&&!Q.empty())
	       Q.pop();
		if(Q.empty())
	        return 	;
	    tp=Q.top();
	    Dis_To[tp.x]=tp.dis;
	    for(Chain *tpp=OP_Head[tp.x];tpp;tpp=tpp->next)
	      Q.push((Node){tpp->other,tpp->len+tp.dis });
	}
}
priority_queue<node> QQ;
int cnt[5001];
double eps=1e-7;
inline void STAR(int start,int end,double Max)
{
	while(!QQ.empty())
	QQ.pop();
	QQ.push((node){Dis_To[start],0,start});
    node tp;
	while(!QQ.empty()) 
      {
      	tp=QQ.top();QQ.pop();
	    if(tp.f-eps>Max)continue;
	    cnt[tp.v]++;
	    if(tp.v==end)
		{
		Max-=tp.g;
		continue;
		}
		for(Chain*T=Head[tp.v];T;T=T->next)
		  if(Dis_To[T->other]!=INF)
		   QQ.push((node){tp.g+T->len+Dis_To[T->other],tp.g+T->len,T->other}); 
	  }
	printf("%d\n",cnt[end]);
}
char c;
inline void read(int &a)
{
	a=0;do c=getchar();while(c<'0'||c>'9');
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
inline void add_Head(int a,int b,double dis)
{
	Chain*tp=new Chain;
	tp->other=b;
	tp->len=dis;
	tp->next=Head[a];
	Head[a]=tp;
}
inline void add_OP_Head(int a,int b,double dis)
{
	Chain*tp=new Chain;
	tp->other=b;
	tp->len=dis;
	tp->next=OP_Head[a];
	OP_Head[a]=tp;
}
int main()
{
	int m;
	read(n),read(m);
	double Max;
    scanf("%lf",&Max);
    double t;
    int i,j,k;
    for(i=1;i<=m;i++)
      read(j),read(k),scanf("%lf",&t),add_Head(j,k,t),add_OP_Head(k,j,t);
	dij(n);
	STAR(1,n,Max);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值