• Evanyou Blog 彩带


    (A*算法:bfs + 估价函数)

    总代价=当前代价+未来估价

    1. 估价函数

    1.1 (f(x) le g(x))

    • (f(x) 从状态x到目标状态的 估价)

    • (g(x) 从状态x到目标状态的 实际代价)

    1.2 Kth路

    常规思路:(BFS),使用优先队列代替传统队列,每次选择距离最近的。但是,这是贪心,策略显然错误。

    正解:仍然(BFS),使用优先队列代替传统队列,每次选择距离最近的。而在插入优先队列的时候,将实际代价替换为总代价。

    #include<bits/stdc++.h>
    #include<cctype>
    #pragma GCC optimize(2)
    #define in(a) a = read()
    #define out(a) write(a)
    #define outn(a) out(a),putchar('
    ')
    #define ll long long
    #define rg register
    #define New int
    using namespace std;
    namespace IO_Optimization{
    	inline New read()
    	{
    	    New X = 0,w = 0;
    		char ch = 0;
    
    		while(!isdigit(ch))
    		{
    			w |= ch == '-';
    			ch=getchar();
    		}
    	    while(isdigit(ch))
    		{
    			X = (X << 3) + (X << 1) + (ch ^ 48);
    			ch = getchar();
    		}
    	    return w ? -X : X;
    	}
    	char F[200] ;
    	inline void write(New x) //快速输出 空间
    	{
    		if(x == 0)
    		{
    			putchar('0');
    			return;
    		}
    
    		New tmp = x > 0 ? x : -x;
    		int cnt = 0;
    
    		if(x < 0)
    			putchar( '-' );
    
    		while(tmp > 0)
    		{
    			F[cnt++] = tmp % 10 + '0';
    			tmp /= 10;
    		}
    
    		while(cnt > 0)
    			putchar(F[--cnt]) ;
    	}
    	#undef New
    }
    using namespace IO_Optimization;
    const int N = 100000 + 2;
    
    int n, m, s, t, k, x, y, z, len, p;
    int dis[N], nxt, val, tot[N];
    struct Node
    {
    	int num, dist;
    	inline bool operator <(const Node &nxt)const{
    		return dist > nxt.dist;
    	}
    };
    vector<Node> nei[N];
    vector<Node> e[N];
    bool vis[N];
    
    inline void Dijkstra(int start)
    {
    	memset(dis,0x3f3f3f3f,sizeof(dis));
    	memset(vis,false,sizeof(vis));
    	priority_queue<Node>q;
    	Node cur = {start,0};
    
    	q.push(cur);
    	dis[start] = 0;
    	vis[start] = true;
    
    	while(!q.empty())
    	{
    		cur = q.top();
    		q.pop();
    		p = cur.num;
    		vis[p] = false;
    		len = nei[p].size();
    
    		for(rg int i = 0;i < len; ++i)
    		{
    			nxt = nei[p][i].num;
    			val = nei[p][i].dist;
    
    			if(dis[nxt] > dis[p] + val)
    			{
    				dis[nxt] = dis[p] + val;
    				if(!vis[nxt])
    				{
    					Node tmp = {nxt,dis[nxt]};
    					q.push(tmp);
    					vis[nxt] = true;
    				}
    			}
    		}
    	}
    	return;
    }
    
    inline void A_star(int s)
    {
    	priority_queue<Node>q;
    	Node now = {s, 0 + dis[s]};
    	if(s == t) 
    		++k;
    	q.push(now);
    	while(!q.empty())
    	{
    		int x = q.top().num;
    		int dist = q.top().dist - dis[x];
    		q.pop();
    		++tot[x];
    		if(tot[t] == k)
    		{
    			outn(dist);
    			return ;
    		}
    		int len = e[x].size();
    		for(rg int i = 0; i < len; ++i)
    		{
    			int nxt = e[x][i].num;
    			int val = e[x][i].dist;
    			if(tot[nxt] < k)
    			{
    				Node tmp = {nxt, dist + val + dis[nxt]};
    				q.push(tmp);
    			}
    		}
    	}
    	puts("-1");
    	return ;
    }
    
    int main()
    {
    	in(n), in(m);
    	for(rg int i = 1;i <= m; ++i)
    	{
    		in(x), in(y), in(z);
    		Node u1 = {x, z};
    		nei[y].push_back(u1);
    		Node u2 = {y, z};
    		e[x].push_back(u2);
    	}
    	in(s), in(t), in(k);
    	Dijkstra(t);
    	A_star(s);
    	return 0;
    }
    

    iddfs

    适用的题目:

    • 答案层次可以直接或间接地知道(较浅)
    • 新增节点随着层次快速增加

    劣势:每一次都要从根节点重新搜索

    伪代码:

    inline bool dfs(int cen)
    {
        if(cen == dep)
        {
            if(存在合法答案)
                return true;
            return false;
        }
        for(cen->next)
            if(dfs(next) == true)
                return true;
    }
    
    while(dfs(toor) == false)
    	++dep;
    cout<<dep;
    
  • 相关阅读:
    go chapter 4
    go chapter 3
    ETCD相关介绍--整体概念及原理方面
    go chapter 2
    go chapter 1
    使用kubeadm搭建kubernetes1.10集群 Posted on April 14, 2018
    单用户passwd修改root密码没反应
    is not in the sudoers file解决方案
    版本更换,开始学习鸟哥的私房菜
    ubuntu 常见命令
  • 原文地址:https://www.cnblogs.com/CJYBlog/p/12952494.html
Copyright © 2020-2023  润新知