题目:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3668
题意:
给一个初始值为0的长度为n的区间,给m个约束l,r,a,b,表示从l到r的区间和>=a且<=b,且每个数的范围为-10000~10000,问这个区间的每个数是多少,要求数尽可能大,且序列字典序最大。
方法:
差分约束系统,以前缀和表示一个节点a[i]
建图:根据下面约束条件建图
a[i]-a[i-1]<=10000
a[i-1]-a[i]<=10000
对于每个条件(l,r,a,b)
a[r]-a[l-1]<=-a
a[l-1]-a[r]<=b
使用最短路尽可能求最大值
(最长路求最小值,最短路求最大值)
1 void add(int l, int r, int a, int b) 2 { 3 addse(l - 1, r, b); 4 addse(r, l - 1, -a); 5 } 6 void input() 7 { 8 for (int i = 1; i <= n; i++) 9 { 10 addse(i, i - 1, 10000); 11 addse(i - 1, i, 10000); 12 } 13 for (int i = 0; i < m; i++) 14 { 15 int l, r, a, b; 16 scanf("%d%d%d%d", &l, &r, &a, &b); 17 add(l, r, a, b); 18 } 19 }
代码:
1 /******************************************** 2 *ACM Solutions 3 * 4 *@Title: ZOJ 3668 Launching the Spacecraft 5 *@Version: 1.0 6 *@Time: 2014-08-26 7 *@Solution: http://www.cnblogs.com/xysmlx/p/xxxxxxx.html 8 * 9 *@Author: xysmlx(Lingxiao Ma) 10 *@Blog: http://www.cnblogs.com/xysmlx 11 *@EMail: xysmlx@163.com 12 * 13 *Copyright (C) 2011-2015 xysmlx(Lingxiao Ma) 14 ********************************************/ 15 // #pragma comment(linker, "/STACK:102400000,102400000") 16 #include <cstdio> 17 #include <iostream> 18 #include <cstring> 19 #include <string> 20 #include <cmath> 21 #include <set> 22 #include <list> 23 #include <map> 24 #include <iterator> 25 #include <cstdlib> 26 #include <vector> 27 #include <queue> 28 #include <stack> 29 #include <algorithm> 30 #include <functional> 31 using namespace std; 32 typedef long long LL; 33 #define pb push_back 34 #define ROUND(x) round(x) 35 #define FLOOR(x) floor(x) 36 #define CEIL(x) ceil(x) 37 const int maxn = 1010; 38 const int maxm = 2000010; 39 const int inf = 0x3f3f3f3f; 40 const LL inf64 = 0x3f3f3f3f3f3f3f3fLL; 41 const double INF = 1e30; 42 const double eps = 1e-6; 43 const int P[4] = {0, 0, -1, 1}; 44 const int Q[4] = {1, -1, 0, 0}; 45 const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1}; 46 const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1}; 47 struct Edge 48 { 49 int u, v, w; 50 int next; 51 } edge[maxm]; 52 int head[maxn], en; 53 void addse(int u, int v, int w) 54 { 55 edge[en].u = u; 56 edge[en].v = v; 57 edge[en].w = w; 58 edge[en].next = head[u]; 59 head[u] = en++; 60 } 61 62 int n, m; 63 int d[maxn]; 64 int pre[maxn];//用于解析路径 65 /*DFS找负环 66 bool cir[maxn]; 67 void dfs(int u) 68 { 69 cir[u]=true; 70 for(int i=head[u]; i!=-1; i=edge[i].next) 71 if(!cir[edge[i].v]) dfs(edge[i].v); 72 } 73 */ 74 bool spfa(int s) 75 { 76 int cnt[maxn]; 77 int mark[maxn]; 78 queue<int> Q; 79 for (int i = 0; i <= n; ++i) d[i] = inf; 80 for (int i = 0; i <= n; ++i) pre[i] = i; //用于解析路径 81 memset(mark, 0, sizeof(mark)); 82 memset(cnt, 0, sizeof(cnt)); 83 d[s] = 0; 84 Q.push(s); 85 mark[s] = 1; 86 cnt[s]++; 87 while (Q.size()) 88 { 89 int u = Q.front(); 90 Q.pop(); 91 mark[u] = 0; 92 for (int i = head[u]; i != -1; i = edge[i].next) 93 { 94 int v = edge[i].v; 95 int w = edge[i].w; 96 if (d[u] + w < d[v]) 97 { 98 pre[v] = u; // 用于解析路径 99 d[v] = d[u] + w; 100 if (mark[v] == 0) 101 { 102 mark[v] = 1; 103 Q.push(v); 104 if (++cnt[v] > n + 1) return false; //有负环,可以用DFS找 105 } 106 } 107 } 108 } 109 return true; 110 } 111 int kase; 112 void init() 113 { 114 kase++; 115 memset(head, -1, sizeof(head)); 116 en = 0; 117 } 118 void add(int l, int r, int a, int b) 119 { 120 addse(l - 1, r, b); 121 addse(r, l - 1, -a); 122 } 123 void input() 124 { 125 for (int i = 1; i <= n; i++) 126 { 127 addse(i, i - 1, 10000); 128 addse(i - 1, i, 10000); 129 } 130 for (int i = 0; i < m; i++) 131 { 132 int l, r, a, b; 133 scanf("%d%d%d%d", &l, &r, &a, &b); 134 add(l, r, a, b); 135 } 136 } 137 void debug() 138 { 139 // 140 } 141 void solve() 142 { 143 if (spfa(0)) 144 { 145 for (int i = 1; i <= n; i++) 146 { 147 if (i < n) printf("%d ", d[i] - d[i - 1]); 148 else printf("%d ", d[i] - d[i - 1]); 149 } 150 } 151 else puts("The spacecraft is broken!"); 152 } 153 void output() 154 { 155 // 156 } 157 int main() 158 { 159 // int size = 256 << 20; // 256MB 160 // char *p = (char *)malloc(size) + size; 161 // __asm__("movl %0, %%esp " :: "r"(p)); 162 163 // std::ios_base::sync_with_stdio(false); 164 #ifdef xysmlx 165 freopen("in.cpp", "r", stdin); 166 #endif 167 168 kase = 0; 169 while (~scanf("%d%d", &n, &m)) 170 { 171 init(); 172 input(); 173 solve(); 174 output(); 175 } 176 return 0; 177 }