poj 3680 Intervals
解题报告:http://blog.sina.com.cn/s/blog_6635898a0100pdlu.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> using namespace std; const int nMax = 405; const int eMax = 1500; struct{ int st, ed, w; }inl[nMax]; struct{ int v, cap, cost, next, re; }edge[eMax]; int n, ans; int k, edgeHead[nMax]; int que[nMax], pre[nMax], dis[nMax]; bool vis[nMax]; int hash[100005]; void addEdge(int u, int v, int ca, int co){ edge[k].v = v; edge[k].cap = ca; edge[k].cost = co; edge[k].next = edgeHead[u]; edge[k].re = k + 1; edgeHead[u] = k ++; edge[k].v = u; edge[k].cap = 0; edge[k].cost = -co; edge[k].next = edgeHead[v]; edge[k].re = k - 1; edgeHead[v] = k ++; } bool spfa(){ int i, head = 0, tail = 1; for(i = 0; i <= n; i ++){ dis[i] = -1; vis[i] = false; } dis[0] = 0; que[0] = 0; vis[0] = true; while(head != tail){ int u = que[head]; for(i = edgeHead[u]; i != -1; i = edge[i].next){ int v = edge[i].v; if(edge[i].cap && dis[v] < dis[u] + edge[i].cost){ dis[v] = dis[u] + edge[i].cost; pre[v] = i; if(!vis[v]){ vis[v] = true; que[tail ++] = v; if(tail == nMax) tail = 0; } } } vis[u] = false; head ++; if(head == nMax) head = 0; } if(dis[n] <= 0) return false; return true; } void end(){ int u, p; for(u = n; u != 0; u = edge[edge[p].re].v){ p = pre[u]; edge[p].cap -= 1; edge[edge[p].re].cap += 1; ans += edge[p].cost; } } int main(){ int t, i, N, K; scanf("%d", &t); while(t --){ memset(edgeHead, -1, sizeof(edgeHead)); memset(hash, 0, sizeof(hash)); scanf("%d%d", &N, &K); for(i = 0; i < N; i ++){ scanf("%d%d%d", &inl[i].st, &inl[i].ed, &inl[i].w); hash[inl[i].st] = hash[inl[i].ed] = 1; } for(k = 1, i = 0; i <= 100000; i ++) // 由于100000不大,所以我用hash离散化。 if(hash[i] == 1) hash[i] = k ++; for(i = 0; i < N; i ++){ // 线段的端点值,改为离散后的下标号。 inl[i].st = hash[inl[i].st]; inl[i].ed = hash[inl[i].ed]; } n = k; k = 0; for(i = 0; i < n; i ++) // 建图。 addEdge(i, i+1, K, 0); for(i = 0; i < N; i ++) addEdge(inl[i].st, inl[i].ed, 1, inl[i].w); ans = 0; while(spfa()) end(); printf("%d\n", ans); } return 0; }