做了这道题目感觉对差分约束的理解又加深了一些。
关于差分约束最后要求的值是最大值还是最小值的问题,求最小值的时候可以反向建边求最短路,也可以转化成a-b>=x的约束然后求最长路。求最大值的时候可以直接求最短路,如果目标距离是INF的话就代表可以任意长。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include <queue> #include <stack> using namespace std; typedef long long LL; const int maxn = 10000 + 5; const int maxm = 500000 + 5; const int INF = INT_MAX / 4; int first[maxn],nxt[maxm],d[maxn],v[maxm],w[maxm]; int N,ML,MD,qcnt[maxn],ecnt; bool inq[maxn]; void adde(int _u,int _v,int _w) { //printf("adde %d %d %d ",_u,_v,_w); v[ecnt] = _v; w[ecnt] = _w; nxt[ecnt] = first[_u]; first[_u] = ecnt; ecnt++; } void solve() { bool bad = false; for(int i = 0;i <= N;i++) { d[i] = INF; inq[i] = false; qcnt[i] = 0; } d[1] = 0; inq[1] = true; queue<int> q; q.push(1); qcnt[1] = 1; while(!q.empty() && !bad) { int x = q.front(); q.pop(); inq[x] = false; for(int i = first[x];i != -1;i = nxt[i]) { if(d[v[i]] > d[x] + w[i]) { d[v[i]] = d[x] + w[i]; if(!inq[v[i]]) { q.push(v[i]); inq[v[i]] = true; qcnt[v[i]]++; if(qcnt[v[i]] > N + 1) { bad = true; break; } } } } } //for(int i = 0;i <= N;i++) printf("%d ",d[i]); putchar(' '); //for(int i = 0;i <= N;i++) printf("%d ",qcnt[i]); putchar(' '); if(bad == true) puts("-1"); else if(d[N] >= INF) puts("-2"); else printf("%d ",d[N]); } int main() { while(~scanf("%d%d%d",&N,&ML,&MD)) { ecnt = 0; memset(first,-1,sizeof(first)); memset(nxt,-1,sizeof(nxt)); for(int i = 1;i <= ML;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); adde(a,b,c); } for(int i = 1;i <= MD;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); adde(b,a,-c); } for(int i = 1;i <= N;i++) { adde(i,i - 1,0); } solve(); } return 0; }