hdu 1384 Intervals (差分约束)
好歹用了一天,也算是看懂了差分约束的原理,做出第一条查分约束了。
题意是告诉你一些区间中最少有多少元素,最少需要多少个元素才能满足所有要求。
构图的方法是,(a)->(b+1)=c。还有就是所有的相邻的点都要连上(i+1)->(i)=0,(i)->(i+1)=-1。因为我对点离散了,所以就变成(rx[i])->(rx[i+1])=rx[i]-rx[i+1]。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #include <iostream> 6 7 using namespace std; 8 9 const int N = 55555; 10 const int INF = 0x55555555; 11 struct Edge { 12 int id, nx, val; 13 Edge() {} 14 Edge(int id, int nx, int val) : id(id), nx(nx), val(val) {} 15 } edge[N << 2]; 16 int eh[N], ec; 17 18 void init() { 19 ec = 0; 20 memset(eh, -1, sizeof(eh)); 21 } 22 23 void addedge(int u, int v, int w) { 24 edge[ec] = Edge(v, eh[u], w); 25 eh[u] = ec++; 26 } 27 28 int rx[N << 1], dis[N]; 29 bool vis[N]; 30 queue<int> Q; 31 32 void spfa(int s) { 33 while (!Q.empty()) Q.pop(); 34 memset(vis, 0, sizeof(vis)); 35 for (int i = 0; i < N; i++) dis[i] = -INF; 36 Q.push(s); 37 vis[s] = true; 38 dis[s] = 0; 39 while (!Q.empty()) { 40 int cur = Q.front(); 41 Q.pop(); 42 vis[cur] = false; 43 for (int t = eh[cur]; ~t; t = edge[t].nx) { 44 if (dis[edge[t].id] < dis[cur] + edge[t].val) { 45 dis[edge[t].id] = dis[cur] + edge[t].val; 46 if (vis[edge[t].id]) continue; 47 Q.push(edge[t].id); 48 vis[edge[t].id] = true; 49 } 50 } 51 } 52 } 53 54 int main() { 55 // freopen("in", "r", stdin); 56 int n, x, y, z; 57 while (~scanf("%d", &n)) { 58 init(); 59 int cnt = 0; 60 for (int i = 0; i < n; i++) { 61 scanf("%d%d%d", &x, &y, &z); 62 addedge(x, y + 1, z); 63 rx[cnt++] = x; 64 rx[cnt++] = y + 1; 65 } 66 sort(rx, rx + cnt); 67 cnt = unique(rx, rx + cnt) - rx; 68 for (int i = 1; i < cnt; i++) addedge(rx[i], rx[i - 1], rx[i - 1] - rx[i]), addedge(rx[i - 1], rx[i], 0); 69 spfa(rx[0]); 70 printf("%d\n", dis[rx[cnt - 1]]); 71 } 72 return 0; 73 }
跑的比较慢,元素进队的次数比较多。用固定大小的queue因为越界WA了好多次。
——written by Lyon