题目:输入n,m个关系。接下来m行每行A,B,C。表示B比A多出来的糖果不超过C个。
问:n号人最多比1号人多几个糖果
思路:差分约束关系,B-A<C可以看作由A做一条有向边到B,权值为C。问题变成了1到N的最短路
这题貌似只能用邻接表+优先队列,反正我平常都这么写的。这题同样也卡scanf
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <string> #include <map> #include <iomanip> #include <algorithm> #include <queue> #include <stack> #include <set> #include <vector> //const int maxn = 1e5+5; #define ll long long ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} //const int inf = 0x6fffffff; #define MAX INT_MAX #define FOR(i,a,b) for( int i = a;i <= b;++i) #define bug cout<<"--------------"<<endl using namespace std; int ver[151000],edge[151000],next[151000],head[151000],vis[151000],d[151000]; int n,m,tot; void add(int x,int y,int z) { ver[++tot] = y,edge[tot] = z,next[tot] = head[x] , head[x] = tot; } void djijiestra() { priority_queue<pair<int,int> >que; memset(d,0x3f,sizeof(d)); d[1] = 0; que.push(make_pair(0,1)); while(que.size()) { int x = que.top().second;que.pop(); if(vis[x] == 1) continue; vis[x] = 1; for(int i=head[x];i;i=next[i]) { int y = ver[i],z = edge[i]; if(d[y] > d[x] + z) { d[y] = d[x] + z; que.push(make_pair(-d[y],y)); } } } } int main() { //ios::sync_with_stdio(false); //cin>>n>>m; scanf("%d %d",&n,&m); FOR(i,1,m) { int x,y,z; scanf("%d %d %d",&x,&y,&z); add(x,y,z); } djijiestra(); printf("%d ",d[n]); }