ACM: 图论题 poj 1201 差分约束
2016-05-19 23:26
309 查看
[align=center]Intervals[/align]
Description
You are given n closed, integer
intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1,
..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least
ci common elements with interval [ai, bi], for each
i=1,2,...,n,
writes the answer to the standard output.
Input
The first line of the input
contains an integer n (1 <= n <=
50000) -- the number of intervals. The following n lines describe
the intervals. The (i+1)-th line of the input contains three
integers ai, bi and ci separated by single spaces and such that 0
<= ai <= bi <= 50000
and 1 <= ci <= bi - ai+1.
Output
The output contains exactly one
integer equal to the minimal size of set Z sharing at least ci
elements with interval [ai, bi], for each i=1,2,...,n.
Sample Input
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
Sample Output
6
题意: 给出N个闭区间[ai, bi], 每个区间有一个ci表示集合Z在区间[ai, bi]内有ci个公共元素,
现在问你在集合Z上至少有多少个公共元素.
解题思路:
1. 明显是差分约束题目, dist[i]表示源点到i的公共元素个数, t_min和t_max分别表示这个集合Z
的上下界, dist[t_max]-dist[t_min]就是区间中至少有多少个公共元素.
2.
题目有2个约束条件:
dist[bi+1] - dist[ai] >= ci; ==>
dist[bi+1] >= dist[ai]+ci
0 <= dist[i+1] - dist[i] <= 1;
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define MAX 50005
const int INF = (1<<28);
struct node
{
int v;
int w;
int next;
}edges[MAX*3];
int n, num;
int first[MAX];
int t_max, t_min;
inline void add(int u, int v, int w)
{
edges[num].v = v;
edges[num].w = w;
edges[num].next = first[u];
first[u] = num++;
}
int spfa()
{
queue qu;
int dist[MAX];
bool vis[MAX];
memset(vis, false, sizeof(vis));
for(int i = t_min; i <= t_max;
++i)
dist[i] = -INF;
dist[t_min] = 0;
qu.push(t_min);
while( !qu.empty() )
{
int u = qu.front();
qu.pop();
vis[u] = false;
for(int e = first[u]; e != -1;
e = edges[e].next)
{
if(
dist[edges[e].v] < dist[u]+edges[e].w )
{
dist[edges[e].v]
= dist[u]+edges[e].w;
if(
!vis[edges[e].v] )
{
vis[edges[e].v]
= true;
qu.push(edges[e].v);
}
}
}
}
return dist[t_max]-dist[t_min];
}
int main()
{
int i;
// freopen("input.txt", "r", stdin);
while(scanf("%d", &n) !=
EOF)
{
memset(first, -1,
sizeof(first));
t_max = -1;
t_min = INF;
int u, v, w;
for(i = 0; i <
n; ++i)
{
scanf("%d %d
%d", &u, &v,
&w);
v++;
if( t_max
< v ) t_max = v;
if( t_min
> u ) t_min = u;
add(u, v,
w);
}
for(i = t_min; i
< t_max; ++i)
{
add(i, i+1,
0);
add(i+1, i,
-1);
}
printf("%d\n",
spfa());
}
return 0;
}
Description
You are given n closed, integer
intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1,
..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least
ci common elements with interval [ai, bi], for each
i=1,2,...,n,
writes the answer to the standard output.
Input
The first line of the input
contains an integer n (1 <= n <=
50000) -- the number of intervals. The following n lines describe
the intervals. The (i+1)-th line of the input contains three
integers ai, bi and ci separated by single spaces and such that 0
<= ai <= bi <= 50000
and 1 <= ci <= bi - ai+1.
Output
The output contains exactly one
integer equal to the minimal size of set Z sharing at least ci
elements with interval [ai, bi], for each i=1,2,...,n.
Sample Input
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
Sample Output
6
题意: 给出N个闭区间[ai, bi], 每个区间有一个ci表示集合Z在区间[ai, bi]内有ci个公共元素,
现在问你在集合Z上至少有多少个公共元素.
解题思路:
1. 明显是差分约束题目, dist[i]表示源点到i的公共元素个数, t_min和t_max分别表示这个集合Z
的上下界, dist[t_max]-dist[t_min]就是区间中至少有多少个公共元素.
2.
题目有2个约束条件:
dist[bi+1] - dist[ai] >= ci; ==>
dist[bi+1] >= dist[ai]+ci
0 <= dist[i+1] - dist[i] <= 1;
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define MAX 50005
const int INF = (1<<28);
struct node
{
int v;
int w;
int next;
}edges[MAX*3];
int n, num;
int first[MAX];
int t_max, t_min;
inline void add(int u, int v, int w)
{
edges[num].v = v;
edges[num].w = w;
edges[num].next = first[u];
first[u] = num++;
}
int spfa()
{
queue qu;
int dist[MAX];
bool vis[MAX];
memset(vis, false, sizeof(vis));
for(int i = t_min; i <= t_max;
++i)
dist[i] = -INF;
dist[t_min] = 0;
qu.push(t_min);
while( !qu.empty() )
{
int u = qu.front();
qu.pop();
vis[u] = false;
for(int e = first[u]; e != -1;
e = edges[e].next)
{
if(
dist[edges[e].v] < dist[u]+edges[e].w )
{
dist[edges[e].v]
= dist[u]+edges[e].w;
if(
!vis[edges[e].v] )
{
vis[edges[e].v]
= true;
qu.push(edges[e].v);
}
}
}
}
return dist[t_max]-dist[t_min];
}
int main()
{
int i;
// freopen("input.txt", "r", stdin);
while(scanf("%d", &n) !=
EOF)
{
memset(first, -1,
sizeof(first));
t_max = -1;
t_min = INF;
int u, v, w;
for(i = 0; i <
n; ++i)
{
scanf("%d %d
%d", &u, &v,
&w);
v++;
if( t_max
< v ) t_max = v;
if( t_min
> u ) t_min = u;
add(u, v,
w);
}
for(i = t_min; i
< t_max; ++i)
{
add(i, i+1,
0);
add(i+1, i,
-1);
}
printf("%d\n",
spfa());
}
return 0;
}
相关文章推荐
- ACM: 搜索题 poj 1020
- ACM: 图论题 poj 3308 最大流问题
- Android的自定义控件起步
- ACM: 图论题 poj 3177 同 3352
- dos批处理中%~dp0%的说明
- ACM: 图论题 poj 2186 强连通分量
- ACM: 博弈题 poj 1143 状态压缩
- 本周学习的代码(数构 深度 广度 优先遍历)
- [原创]关于设置linux中vim 显示行号
- ACM: 动态规划题 poj&nb…
- ACM: 图论题 poj 3…
- 兴趣学习: opencv 实现画图程序
- 兴趣学习: opencv -- 视频读写, 鼠…
- ACM: 动态规划题 poj 2923
- ACM: 动态规划题 poj&nb…
- ACM: 动态规划题 poj 3093 0-1背包
- ACM: 动态规划题 poj&nb…
- ipvsadm-2 DR模式及自动检测后端服务器状态
- ACM: 动态规划题 poj 3211 背包变…
- ACM: 动态规划题 poj&nb…