• poj 2449 Remmarguts' Date 第K短路


    题意:给一个有向图,告诉起点和终点,求第K短路

    解法:dijkstra+A*,正反两个邻接表

    总结:做完这个题学会了dijkstra算法,对A*有了一点了解

    PS.优先队列里的比较函数变量写错了,MLE了3天,恶心死我了。膜拜无语神牛,几分钟就指导我搞定了

    /*
    Problem: 2449		User: fancy081
    Memory: 6472K		Time: 250MS
    Language: C++		Result: Accepted
    */
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    
    const int MAXN=1005;
    const int MAXM=100005;
    const int INF=100000000;
    
    int N,M,Start,Te,Kth;
    short v[MAXM],rev[MAXM],w[MAXM];
    int next[MAXM];
    int renext[MAXM];
    int first[MAXN],refirst[MAXN];
    int h[MAXN];
    
    struct nod
    {
    	int len,pos;
    	bool operator<(const nod &x)const
    	{
    		return x.len<len;
    	}
    };
    priority_queue<nod> Que;
    
    void dijkstra()
    {
    	bool done[MAXN];
    	while(!Que.empty()) Que.pop();
    	for(int i=1;i<=N;i++) {h[i]=INF;done[i]=false;}
    	h[Te]=0;	
    	nod tmp,iq;
    	tmp.len=0;tmp.pos=Te;
    	Que.push(tmp);
    	int uu,vv,dd;
    	while(!Que.empty())
    	{
    		tmp=Que.top();Que.pop();
    		uu=tmp.pos;
    		if(done[uu]) continue;
    		dd=tmp.len;
    		done[uu]=true;
    		for(vv=refirst[uu];vv!=-1;vv=renext[vv])
    		{
    			if(dd+w[vv]<h[rev[vv]])
    			{
    				h[rev[vv]]=dd+w[vv];
    				iq.len=h[rev[vv]];
    				iq.pos=rev[vv];
    				Que.push(iq);			
    			}
    		}
    	}
    }
    
    struct nodx
    {
    	int f,pos;
    	bool operator<(const nodx &x)const
    	{
    		return x.f<f;
    	}
    };
    priority_queue<nodx> Quex;
    int astar()
    {
    	nodx tmp,iq;
    	while(!Quex.empty()) Quex.pop();
    	int cnt[MAXN];
    	for(int i=1;i<=N;i++) cnt[i]=0;
    	tmp.f=h[Start];tmp.pos=Start;
    	Quex.push(tmp);
    	int ff,now,gg,vv;
    	while(!Quex.empty())
    	{
    		tmp=Quex.top();Quex.pop();
    		ff=tmp.f;now=tmp.pos;
    		gg=tmp.f-h[now];
    		cnt[now]++;
    		if(cnt[now]>Kth) continue;
    		if(cnt[Te]==Kth) return ff;
    		for(vv=first[now];vv!=-1;vv=next[vv])
    		{
    			iq.f=gg+w[vv]+h[v[vv]];
    			iq.pos=v[vv];
    			Quex.push(iq);
    		}
    	}
    	return -1;
    }
    
    int main()
    {
    	while(scanf("%d%d",&N,&M)!=EOF)
    	{
    		for(int i=0;i<=N;i++) {first[i]=-1;refirst[i]=-1;}
    		for(int e=0;e<M;e++)
    		{
    			scanf("%d%d%d",&rev[e],&v[e],&w[e]);
    			next[e]=first[rev[e]];
    			first[rev[e]]=e;
    			renext[e]=refirst[v[e]];
    			refirst[v[e]]=e;
    		}		
    		scanf("%d%d%d",&Start,&Te,&Kth);
    		if(Start==Te) Kth++;
    		dijkstra();
    	        printf("%d\n",astar());
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Linux 关机和重启命令
    Linux ubuntu安装ftp服务器
    C++ map和unsorted_map底层实现
    C++中的那些容器在使用时,哪些情况下迭代器会失效
    虚函数表的构造
    C++容器 priority_queue,堆的实现
    c++11中的move是否会改变对象的地址
    (转)关于linux中内核编程中结构体的赋值操作(结构体指定初始化)
    无参方法
    类和对象
  • 原文地址:https://www.cnblogs.com/laputa/p/2196946.html
Copyright © 2020-2023  润新知