每日打卡(1/1)
传送门:点击打开链接
题目大意:
n个人,m钟比较,每行的信息是3个数字,A,B,C,表示B比A多出来的糖果不超过C个,问你,n号人最多比1号人多几个糖果
题目思路:
可以观察以下三角不等式:
B-A>x
C-B>y
C-A>z
那么,C-A的最大值就是min(z,x+y),刚开始我认为最大值应该是x+y,仔细思考后发现,由于第三个条件,所以最大值一定是两者之间的较小值。这种问题,我们称为差分约束问题。
对于这种问题的求解,我们可以采用最短路的思想,因为其松弛过程和比较过程是相对应的。所以用dijkstra求起点到终点的最短路,即可解决该问题。
由于本题数据卡的很厉害,所以以往的优先队列版dijkstra模板需要修改。
(1)需要用链式前向星代替vector。链式前向星我会再写一篇博客。
(2)需要添加vis数组,否则会TLE。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
using namespace std;
const int maxn = 300005;
struct node{
int next,y,cost;
}E[maxn];
int t,n,d[maxn],m,head[maxn];
bool vis[maxn];
void init()
{
memset(head,-1,sizeof(head));
memset(d,0x3f3f3f,sizeof(d));
}
int main()
{
// freopen("d://test.txt","r",stdin);
scanf("%d%d", &n,&m);
init();
int tot = 0;
while(m--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
E[tot].next = head[x];
E[tot].y = y;
E[tot].cost = z;
head[x] = tot++;
}
int s,e;
s = 1,e = n;
d[s] = 0;
priority_queue<pair<int,int> >q;
q.push(make_pair(-d[s],s));
while(!q.empty())
{
int now = q.top().second;
q.pop();
if(vis[now]) continue;
vis[now] = 1;
for(int i=head[now];i!=-1;i=E[i].next)
{
int v = E[i].y;
if(d[v]>d[now]+E[i].cost)
{
d[v] = d[now]+E[i].cost;
q.push(make_pair(-d[v],v));
}
}
}
cout<<d[e]<<endl;
return 0;
}