zoukankan      html  css  js  c++  java
  • 【混合】【二分】【最短路】二分最短路模型【CF】G.It is all about wisdom

    Mixed——二分最短路模型——G.It is all about wisdom

    考时bfs,dfs加剪枝(dfs在最坏情况下的剪枝相当于bfs加剪枝,其实bfs加剪枝,有点奇怪,一些剪枝在bfs的作用下并不能发挥很好的效果),在第二点的时候都t了,对于至少这类问题应该从二分的角度出发,而不是用求稳的思想,每一个点,每一条路都大概率地去尝试。(二分的check是有一定的原则去办事情,而普通的找是以相对弱的原则来办事情)

    思路:二分是为了迅速找到一个值(智商值),如果能够以这个智商值过了就过了(最短路是为了尽可能压缩金钱的消耗,看一下最小花费会不会小于身上带的钱),并且还要尽可能逼近最优的智商值。

    二分

    • 目的:为了从众多的可能的答案中快速找到最优答案,节省时间,如果有遇到time limited 的情况,可以考虑一下使用二分的写法

      换种角度来思考什么叫做可能的答案可能的答案,它的答案是一个范围,比如说至少,比如说至多,严格小于,less than.....

    • 二分的前提:单调性

    • 内容:

      • check函数

        (把最短路的算法融进来)

      • 边界的写法

    bool check()
    {
         if(条件) return true;
         return false;
    }
    
    • 二分模板
    while(l<=r)
    {
        mid = l+(r-l)>>1;
        if(check(mid))
            r=r-1,ans=r;//趁机保留答案
        else l=l+1;
    }
    

    最短路

    int dijkstra(int st,int ed,int 二分尝试的点)
    {
          小根堆
          使用情况的使用数组
          将起点压入小根堆
          
          while(heap.size())
          {
               提取
               将提取出的结点的使用情况标记为已使用
               
               for 扫描提取出来的点的周围的所有边
                   特殊情况 continue
                   路径更不上时代 continue
                   松弛操作
          }
          因为是二分,判断一下dist[ed]和二分尝试的点的关系,再看一下要return什么
    }
    

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1E5+10,M = 2E5+10,INF = 0x3f3f3f3f;
    typedef pair<int,int > PII;
    int h[N],e[M],ne[M],w[M],limit[M],idx;
    int n,m,cost;
    void add(int a,int b,int c,int d)
    {
    	e[idx]=b,ne[idx]=h[a],w[idx]=c,limit[idx]=d,h[a]=idx++;
    }
    bool check(int x)
    {
    	int dist[n+1];//用dijkstra算法找到最小花费
    	bool used[n+1]; 
    	memset(dist,0x3f,sizeof(dist));
    	memset(used,false,sizeof(used));
    	priority_queue<PII,vector<PII>,greater<PII> > heap;
    	heap.push(PII{0,1});
    
    	while(heap.size())
    	{
    		PII t = heap.top();
    		heap.pop();
    		int d = t.first,u = t.second;
    	    if(used[u])continue;
    		used[u]=true; 
    	
    		for(int i=h[u];~i;i=ne[i])
    		{
    			int j = e[i];
    			if(limit[i]>x||d+w[i]>cost)continue;//没有资格进入途径 
    			if(dist[j]>d+w[i])
    			{
                    dist[j]=d+w[i];
    				heap.push(PII(dist[j],j));
    			}
    		}
    	}
    	if(dist[n]<cost) return true;
    	return false; 
    }
    
    int main()
    {
    	int T;
    	cin>>T;
    	while(T--)
    	{
    		int l=0,r=0,mid;
    		scanf("%d%d%d",&n,&m,&cost);
            
            memset(h,-1,sizeof(h));
            idx=0;//记得归零 
            
            for(int i=0;i<m;i++)
    		{
    		   	int aa,bb,mon,wis;
    		   	cin>>aa>>bb>>mon>>wis;
    		   	add(aa,bb,mon,wis);add(bb,aa,mon,wis);
    		   	r=max(r,wis);
    		}		
    
    		int ans=-1;
    		while(l<=r)
    		{
    			mid = l + (r-l)/2;
    			if(check(mid))
    			   ans=mid,r=mid-1;
    			else l=mid+1;
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    

    其他

    • 在使用链式前向星的写法的时候,不单要把h数组重新设置为-1,也要把idx归零在处理多组数据的时候).
    • 无向边记得乘2
  • 相关阅读:
    HDU 5363 Key Set(快速幂取模)
    HDU 5339 Untitled(暴搜)
    POJ 2406 Power Strings
    Dedecms备份还原网站有效方法
    DEDECMS文章列表每隔8行文章添加分隔虚线
    DEDECMS突破TAG和关键字长度的限制
    为织梦dedecms制作全文RSS订阅源
    DedeCms中Channel用typeid无效
    织梦CMS/Dedecms添加自定义函数
    sql批量换dedecms文章来源和作者
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15106311.html
Copyright © 2011-2022 走看看