Question Link
差分约束系统对应的最短路。
题意:
n个人,m个约束,约束是,由,A,B,C,三个数字组成。B比A多出来的糖果不超过C个,问,n号人最多比1号人多几个糖果?
解法:
对应最短路模型,在松弛完最短路后则变为 d[v] <= d[u] + w ,转化为 d[v] - d[u] <= w,这个和上面的 B - A <= C 是相同的模式 , 因此建图的时候只需要单向图,以1为起点,n为终点跑dijkstra即可。
与最短路模型的差异
每次贪心取得最大的约束,这样才能使得最后n到1的约束最大。
对应代码差异
struct qnode{
int v,w;
qnode(int _v=0,int _c=0):v(_v),w(_c){}
bool operator < ( const qnode &r)const {
return w > r.w;
}
};
AC code
#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std;
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val) memset(var,val,sizeof(var))
#define LL long long
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x) rand()%(x)
#define lowbit(x) x&(-x)
inline int read()
{
int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
while ( a>='0' && a<='9' ){ x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define N 30010
#define M 150010
struct edge{
int u,v,w,nx;
}e[M];int tot,hea[N];bool inq[N];int n,m,dis[N];
struct qnode{
int v,w;
qnode(int _v=0,int _c=0):v(_v),w(_c){}
bool operator < ( const qnode &r)const {
return w > r.w;
}
};
inline void addead(int u,int v,int w){
++tot;
e[tot].u = u; e[tot].v = v; e[tot].w = w; e[tot].nx = hea[u]; hea[u] = tot;
}
void init(){
mset(hea,0);
mset(inq,0);
mset(dis,0x3f);
tot = 0;
}
void dijkstra(){
priority_queue<qnode>q;
while ( !q.empty() ) q.pop();
q.push( qnode(1,0) );
// inq[ 1 ] = 1;
dis[ 1 ] = 0;
while ( !q.empty() ){
qnode tem = q.top();
q.pop();
int u = tem.v;
if ( inq[ u ] ) continue;
inq[ u ] = 1;
for (int i = hea[u]; i ; i = e[i].nx){
if ( dis[ e[i].v ] > dis[ u ] + e[i].w ){
dis[ e[i].v ] = dis[ u ] + e[i].w ;
if ( inq[ e[i].v ] == 0 ){
// inq[i] = 1;
q.push( qnode( e[i].v,dis[ e[i].v ]) );
}
}
}
}
}
int main()
{
// freopen("1.txt","r",stdin);
srand((int)time(0));
// std::ios::sync_with_stdio(false);
while ( scanf("%d%d",&n,&m) != EOF ){
init();
rep(i,1,m){
int u,v,w;
u = read(); v = read(); w = read();
addead(u,v,w);
}
dijkstra();
printf("%d\n",dis[n]);
}
return 0;
}