我是靠谱客的博主 甜蜜小丸子,这篇文章主要介绍NKOI 1599 最大身高,现在分享给大家,希望可以做个参考。

【Usaco Jan07 Silver】最大身高

Time Limit:10000MS  Memory Limit:265536K
Total Submit:146 Accepted:70 
Case Time Limit:1000MS

Description

FJ的N(1 <= N <= 5,000)头奶牛站成一排,并从左到右被编号为1..N。每头奶牛都有一个正整数的身高,具体的值FJ暂时保密,但会告诉你它们当中最高的一头的编号I和身高H(1 <= H <= 1,000,000)的值。 

FJ制作一张包含R(0 <= R <= 10,000)行的列表,每行的都是形如“第17号奶牛能看到第34号奶牛”,其意义是34号奶牛的身高不低于17号奶牛的身高,并且在17号和34号之间的奶牛的身高都严格低于17号奶牛的身高。 

请你确定奶牛每头奶牛的最大可能的身高,我们保证给出的数据都是正确的,并且一定有满足限制条件的解。

Input

第1行:包含四个用空格分开的整数:N, I, H 和 R 
第2..R+1行:每行包含两个用空格分开的整数A和B(1 <= A,B <= N),表示奶牛A能看到奶牛B

Output

第1..N行:第i行包含一个整数,表示第i头奶牛的最大身高。

Sample Input

复制代码
1
2
3
4
5
6
9 3 5 5 1 3 5 3 4 3 3 7 9 8

Sample Output

复制代码
1
2
3
4
5
6
7
8
9
5 4 5 3 4 4 5 5 5

此题要用到差分约束系统的知识

根据输入数据可得:

x1-x3<=0
x2-x1<=-1
x5-x3<=0
x4-x5<=-1
x4-x3<=0
x3-x7<=0
x4-x3<=-1
x5-x3<=-1
x6-x3<=-1
x9-x8<=0

因此我们可以把每一个奶牛看成一个点,把他们之间的不等关系用来构图

例如x5-x3<=-1,则编号为3的点到编号为5的点的权值为-1

注意,当3能看到7时,中间的区间内也可能会出现3能看见4,5,6的情况(虽然并没有影响)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<cstdio> #include<iostream> #include<queue> #include<cstring> using namespace std; const int inf=999999999; int n,o,h,r,cnt; inline void _read(int &x){//读入优化 char t=getchar();bool sign=true; while(t<'0'||t>'9') {if(t=='-')sign=false;t=getchar();} for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0'; if(!sign)x=-x; } int next[1000005],end[1000005],last[1000005],len[1000005]; int dis[5005]; bool f[5005]; queue<int>q; void _input(int a,int b,int l){ end[++cnt]=b; len[cnt]=l; next[cnt]=last[a]; last[a]=cnt; }//存边函数 void spfa(){ int i,y,t,x; for(i=1;i<=n;i++)dis[i]=inf; q.push(0); f[0]=true; dis[0]=h; while(!q.empty()){ x=q.front(); q.pop(); f[x]=false; t=last[x]; while(t!=0){ y=end[t]; if (dis[x]+len[t]<dis[y]){ dis[y]=dis[x]+len[t]; if(!f[y]){ f[y]=true; q.push(y); } } t=next[t]; } } }//用存边优化的SPFA int main(){ int i,j,a,b; _read(n);_read(o);_read(h);_read(r); for(i=1;i<=n;i++)_input(0,i,0); for(i=1;i<=r;i++){ _read(a); _read(b); _input(b,a,0); if(a>b) for(j=b+1;j<a;j++) _input(a,j,-1); else for(j=a+1;j<b;j++) _input(a,j,-1); } spfa(); for(i=1;i<=n;i++) printf("%dn",dis[i]); }

最后

以上就是甜蜜小丸子最近收集整理的关于NKOI 1599 最大身高的全部内容,更多相关NKOI内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部