囧,还是暴露出了对差分约束理解的不透彻。。。
一开始根据开始和结束的关系建边,然后建立一个超级源点,连接每一个其他节点,先把这个点入队。本质上相当于把一开始所有的节点都入队了,然后做一遍最长路(最短路,怎么建边的怎么来),相当于把每一个点都作为起点做了一遍最短路,每个点的d取最大的那个。
#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 = 2000; const int maxm = 6e5; const int INF = INT_MAX / 4; int first[maxn],nxt[maxm],d[maxn],qcnt[maxn]; int n,v[maxm],w[maxm],ecnt,last[maxn]; bool inq[maxn]; char buf[1024]; void adde(int uu,int vv,int ww) { //printf("add %d %d %d\n",uu,vv,ww); v[ecnt] = vv; w[ecnt] = ww; nxt[ecnt] = first[uu]; first[uu] = ecnt; ecnt++; } bool spfa(int str) { bool bad = false; queue<int> q; for(int i = 0;i <= n;i++) { d[i] = -INF; inq[i] = false; qcnt[i] = 0; } q.push(str); qcnt[str] = 1; d[str] = 0; inq[str] = true; while(!q.empty()) { 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]]) { qcnt[v[i]]++; inq[v[i]] = true; q.push(v[i]); if(qcnt[v[i]] > n + 1) { return false; } } } } } return true; } void solve() { if(spfa(0) == false) puts("impossible"); else { for(int i = 1;i <= n;i++) { printf("%d %d\n",i,d[i]); } } } int main() { int kase = 1; while(scanf("%d",&n),n) { printf("Case %d:\n",kase++); memset(first,-1,sizeof(first)); memset(nxt,-1,sizeof(nxt)); ecnt = 0; for(int i = 1;i <= n;i++) { scanf("%d",&last[i]); } while(scanf("%s",buf),buf[0] != ‘#‘) { int a,b; scanf("%d%d",&a,&b); if(strcmp(buf,"SAF") == 0) adde(b,a,last[b]); if(strcmp(buf,"FAF") == 0) adde(b,a,last[b] - last[a]); if(strcmp(buf,"SAS") == 0) adde(b,a,0); if(strcmp("FAS",buf) == 0) adde(b,a,-last[a]); } //建立超级源点 for(int i = 1;i <= n;i++) { adde(0,i,0); } solve(); puts(""); } return 0; }
HDU1534 Schedule Problem 差分约束,布布扣,bubuko.com
原文地址:http://www.cnblogs.com/rolight/p/3860084.html