5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
6
题目大意:
给出一些区间[ai,bi]和每个区间最少需要几个点ci,然后问总共最少需要几个点满足所有区间的要求。比如给出1 5 2和 4 6 2,就是说1到5需要2个点,4到6需要2个点,那么最少需要2个点就可以满足条件了。
</pre><pre name="code" class="cpp">#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue> #define maxn 50050 #define INF 0x3f3f3f3f using namespace std; struct node { int u, v, w, next; }; node edge[maxn * 4]; int head[maxn], cnt; int dist[maxn]; bool vis[maxn]; int maxl, maxr; //区间最左段与最右端 void init(){ cnt = 0; memset(head, -1, sizeof(head)); maxr = 0; maxl = maxn; } void add(int u, int v, int w){ edge[cnt] = {u, v, w, head[u]}; head[u] = cnt++; } void SPFA(){ for(int i = maxl; i <= maxr + 1; ++i){//集合的最左端为源点 dist[i] = -INF; vis[i] = 0; } dist[maxl] = 0; queue<int>q; vis[maxl] = 1; q.push(maxl); while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].v; int w = edge[i].w; if(dist[v] < dist[u] + w){ //最长路 dist[v] = dist[u] + w; if(!vis[v]){ vis[v] = 1; q.push(v); } } } } printf("%d\n", dist[maxr + 1]); return ; } int main (){ int T; while(scanf("%d", &T) != EOF){ init(); int x , y, num; while(T--){ scanf("%d%d%d", &x, &y, &num); maxl = min(maxl, x); maxr = max(maxr, y); add(x, y + 1, num); } for(int i = maxl; i <= maxr + 1; ++i){ add(i, i + 1, 0); add(i + 1, i, -1); } SPFA(); } return 0; }