思路就是DAG上的dp求最短路,然后过了样例和自己造的几组数据,但交上去后所有点都在输出负数
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<map>
#include<cstring>
#define INF 2e18
using namespace std;
const int N=1e5+5;
// 考虑同一位置有多个加油站
struct Node
{
int c,x;
int left,right;
Node(int c,int x):c(c),x(x),left(-1),right(-1) {}
bool operator <(const Node& rhs) {
return (x<rhs.x) || (x==rhs.x && c<rhs.c);
}
};
vector<Node> Nodes;
map<int,int> NodeLoc; // 去掉同位置重复加油站
long long dp[N]; // 记录走到该加油站消费的最小价格
int maxprice=INF;
int Locnum=0;
int s,t;
void linkgraph()
{
for(int i=0;i<Nodes.size();i++)
{
Node& ans=Nodes[i];
if(ans.c>maxprice)
continue;
if(ans.x==s)
Locnum=i;
for(int j=i-1;j>=0;j--)
{
if(Nodes[j].c<ans.c)
{
ans.left=j;
break;
}
}
for(int j=i+1;j<Nodes.size();j++)
{
if(Nodes[j].c<ans.c)
{
ans.right=j;
break;
}
}
}
}
long long dfs(int Loc)
{
if(dp[Loc])
return dp[Loc];
Node& ans=Nodes[Loc];
if(ans.c==0)
return 0;
dp[Loc]=INF;
if(ans.left!=-1)
dp[Loc]=min(dp[Loc],dfs(ans.left)+ans.c*(abs(ans.x-Nodes[ans.left].x)));
dp[Loc]=min(dp[Loc],dfs(ans.right)+ans.c*(abs(Nodes[ans.right].x-ans.x)));
return dp[Loc];
}
int main()
{
int n;
cin>>n>>s>>t;
memset(dp,0,sizeof(dp));
int ci,xi;
long long answer;
while(n--)
{
scanf("%d%d",&ci,&xi);
if(xi>=t)
continue;
if(xi==s)
maxprice=ci<maxprice?ci:maxprice;
if(NodeLoc.count(xi))
{
if(ci<Nodes[NodeLoc[xi]].c)
Nodes[NodeLoc[xi]]=Node(ci,xi);
else
continue;
}
else
{
NodeLoc[xi]=Nodes.size();
Nodes.push_back(Node(ci,xi));
}
}
Nodes.push_back(Node(0,t));
sort(Nodes.begin(),Nodes.end());
linkgraph();
answer=dfs(Locnum);
cout<<answer;
return 0;
}