zoukankan      html  css  js  c++  java
  • [SDOI2010]魔法猪学院

    K短路,A*

    新鲜出炉的A*
    A是什么,其实就是bfs,只不过加了一个估价函数h(x),并把队列换成了优先队列。令h(x)==已经花费的代价,f(x)=g(x)+h(x),,那么f(x)就是优先队列的比较标准。这样我们就会尽可能向最优解的方向搜索,我们如果想要求最优解,就跑A,每次扩展状态,压入队列中,如果感觉要T了,直接结束程序,那么解极为可能就是最优解。

    K短路有一个性质:估价函数是100%正确的,我们就利用优先队列扩展状态,如果我们到达了终点,就cnt++一次,直到cnt==k为止。这样我们就不会重复搜索。
    但是,这种算法空间复杂度极高,IDA*正在学。

    code:(92分)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<vector>
    #include<stack>
    #define db double
    using namespace std;
    const int maxn=400006;
    int head[maxn],cur,fhead[maxn];
    struct hzw
    {
    	int to,next;
    	db v;
    }e[maxn],ed[maxn];
    inline void add(int a,int b,db c,hzw e[],int head[])
    {
    	e[cur].to=b;
    	e[cur].next=head[a];
    	e[cur].v=c;
    	head[a]=cur++;
    }
    typedef pair <double,int>p;
    int n,m;
    double dis[maxn];
    double k;
    inline void dij(int firs)
    {
    	for (int i=1;i<=n;++i) dis[i]=1e17;
    	priority_queue<p,vector<p>,greater<p> >q;
    	q.push(p(0,firs));
    	dis[firs]=0;
    	while (!q.empty())
    	{
    		p fr=q.top();
    		q.pop();
    		int s=fr.second;
    		if (dis[s]<fr.first) continue;
    		for (int i=fhead[s];i!=-1;i=ed[i].next)
    		{
    			int v=ed[i].to;
    			double w=ed[i].v;
    			if (dis[v]>dis[s]+w)
    			{
    				dis[v]=dis[s]+w;
    				q.push(p(dis[v],v));
    			}
    		}
    	}
    }
    struct gk
    {
    	db l,rnd;
    	int id;
    	bool operator <(const gk &rhs) const
    	{
    		return l+rnd>rhs.l+rhs.rnd;
    	}
    };
    inline int A_star(double lmt)
    {
    	priority_queue<gk>q;
    	int cnt=0;
    	q.push((gk){0,dis[1],1});
    	while (!q.empty())
    	{
    		gk all=q.top();
    		q.pop();
    		int s=all.id;
    		db leth=all.l,fina=all.rnd;
    		if (s==n)
    		{
    			lmt-=leth;
    			if (lmt<=0) return cnt;
    			cnt++;
    			continue;
    		}
    		for (int i=head[s];i!=-1;i=e[i].next)
    		{
    			int v=e[i].to;
    			double w=e[i].v;
    			q.push((gk){leth+w,dis[v],v}); 
    		} 
    	}
    	return cnt;
    }
    signed main()
    {
    	memset(head,-1,sizeof(head));
    	memset(fhead,-1,sizeof(fhead));
    	cin>>n>>m>>k;
    	for (int i=1,a,b;i<=m;++i)
    	{
    		db c;
    		scanf("%d%d%lf",&a,&b,&c);
    		add(a,b,c,e,head);
    		add(b,a,c,ed,fhead);
    	}
    	dij(n);
    	cout<<A_star(k);
    	return 0;
    }
    

    总结:

    A*算法适合解决寻找路径问题,她能尽可能的像最优解逼近。

  • 相关阅读:
    (转)详谈高端内存和低端内存
    高级声明------定义一个函数指针数组指针
    A Bug's Life POJ
    How Many Answers Are Wrong HDU
    A
    B
    数据处理----离散化
    Serval and Parenthesis Sequence CodeForces
    D
    C
  • 原文地址:https://www.cnblogs.com/bullshit/p/9689763.html
Copyright © 2011-2022 走看看