zoukankan      html  css  js  c++  java
  • [洛谷P7480] Reboot from Blue

    前言

    你老惦记你那 (O(n)) 的贪心干啥?

    题目

    洛谷

    讲解

    首先我们有一个很明显的结论:选择加油的加油站的油价一定单调不增。

    所以我们对于每个加油站,将它向它前后第一个油价不高于它的加油站连边,然后跑最短路即可。

    当然终点的油价要赋为最小值。

    连边操作可以用单调栈执行。

    代码

    //12252024832524
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define TT template<typename T>
    using namespace std; 
    
    typedef long long LL;
    const int MAXN = 100005;
    const LL INF = (1ll << 60);
    int n,S,T,IDS,IDT;
    int q[MAXN],now;
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    struct node
    {
    	int c,x;
    	bool operator < (const node &px) const{
    		return x < px.x;
    	}
    }s[MAXN];
    int head[MAXN],tot;
    struct edge
    {
    	int v,nxt;LL w;
    }e[MAXN << 1];
    void Add_Edge(int x,int y,LL z)
    {
    	e[++tot].v = y;
    	e[tot].w = z;
    	e[tot].nxt = head[x];
    	head[x] = tot;
    }
    
    struct dij
    {
    	int x; LL w;
    	dij(){}	
    	dij(int x1,LL w1){
    		x = x1;
    		w = w1;
    	}	
    	bool operator < (const dij &px)const{
    		return w > px.w;
    	}
    };
    LL dis[MAXN];
    void bfs()
    {
    	for(int i = 1;i <= n;++ i) dis[i] = INF;
    	priority_queue<dij> q;
    	q.push(dij(IDS,dis[IDS] = 0));
    	while(!q.empty())
    	{
    		dij p = q.top(); q.pop();
    		if(p.w > dis[p.x]) continue;
    		if(p.x == IDT) break;
    		for(int i = head[p.x]; i ;i = e[i].nxt)
    			if(p.w + e[i].w < dis[e[i].v])
    				q.push(dij(e[i].v,dis[e[i].v] = p.w + e[i].w));
    	}
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read(); S = Read(); T = Read();
    	for(int i = 1;i <= n;++ i) 
    	{
    		s[i].c = Read(),s[i].x = Read();
    		if(s[i].x == T) IDT = 1,s[i].c = 0;
    	}
    	if(!IDT) s[++n].c = 0,s[n].x = T;
    	sort(s+1,s+n+1);
    	now = 0;
    	for(int i = 1;i <= n;++ i)
    	{
    		if(s[i].x == S) IDS = i;
    		if(s[i].x == T) IDT = i;
    		while(now >= 1 && s[i].c < s[q[now]].c) now--;
    		if(now) Add_Edge(i,q[now],1ll * Abs(s[i].x - s[q[now]].x) * s[i].c);
    		q[++now] = i;
    	}
    	now = 0;
    	for(int i = n;i >= 1;-- i)
    	{
    		while(now >= 1 && s[i].c < s[q[now]].c) now--;
    		if(now) Add_Edge(i,q[now],1ll * Abs(s[i].x - s[q[now]].x) * s[i].c);
    		q[++now] = i;
    	}
    	bfs();
    	Put(dis[IDT]);
    	return 0;
    }
    
  • 相关阅读:
    linux中文字体
    连接数据库服务器端的几个常见错误
    分布式部署下的报表调用 API调用 权限问题以及性能方案
    报表在IBM AIX系统下resin部署
    ASP.Net与JSP如何共享Session值
    async与await
    从小程序到小程序云开发
    什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?
    微信小程序知识云开发
    变量的解构赋值
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14677066.html
Copyright © 2011-2022 走看看