poj1201(图论)

来源:互联网 发布:猎鲸狂人软件 编辑:程序博客网 时间:2024/05/16 07:02

poj1201

题意:给定闭区间[a,b],至少有x个数,有若干个区间,则至少有多少个数?

思路:即sum[b] - sum[a-1] >= x;可联想到查分约束,寻找其他条件 0 <= sum[b]-sum[b-1] <= 1;构图,找出最长路

#include <iostream>#include <queue>#include <cstring>#include <cstdio>#include <string>#include <cmath>using namespace std;#define MAX(a,b) (a > b ? a : b)#define MIN(a,b) (a < b ? a : b)const int INF = (1 << 31) -1;const int Maxn = 50005;int n,N,u,v,w,Min,Max;int vis[Maxn];int d[Maxn];int head[Maxn];struct node{int v;int w;int next;}edge[Maxn*3];void add_edge(int u, int v, int w){edge[N].v = v;edge[N].w = w;edge[N].next = head[u];head[u] = N++;}void spfa(){for (int i = Min; i <= Max; ++i){d[i] = -INF;}d[Min] = 0;queue<int> q;q.push(Min);while(!q.empty()){int x = q.front();q.pop();vis[x] = 0;for (int i = head[x]; i != -1; i = edge[i].next){if (d[edge[i].v] < d[x] + edge[i].w){d[edge[i].v] = d[x] + edge[i].w;if (!vis[edge[i].v]){vis[edge[i].v] = 1;q.push(edge[i].v);}}}}}int main(){while(~scanf("%d", &n)){Min = INF;Max = -INF;memset(head,-1,sizeof(head));memset(vis,0,sizeof(vis));memset(d,0,sizeof(d));for (int i = 0; i < n; i++){scanf("%d%d%d", &u, &v,&w);add_edge(u,v+1,w);Min = MIN(Min, u);Max = MAX(Max, v+1);}for (int i = Min; i < Max; i++){add_edge(i,i+1,0);add_edge(i+1,i,-1);}spfa();printf("%d\n", d[Max]);}}


0 0
原创粉丝点击