Description
FJ有N(1 <= N <= 10,000)头奶牛,编号为1到N,站成一条直线。每头奶牛自己的身高(正整数,秘密未知),告诉你最高奶牛的身高H及位置I,同时告诉你R(0 <= R <= 10,000)组信息,每组信息由两个数ai,bi组成,表示奶牛ai可以看到奶牛bi,这就意味着奶牛bi的身高至少和奶牛ai的身高一样高,同时奶牛ai到奶牛bi之间的奶牛身高必须低于奶牛ai
现在要你求出每头奶牛最高可能的高度,保证有解。
Input
第1行输入4个空格隔开的整数N,I,H,R
第2到R+1行,每行两个空格隔开的不同的整数A,B(1<=A,B<=N),表示奶牛A能看到奶牛B
Output
第1到N行,每行一个整数表示每只奶牛最高可能的高度。
Sample Input
9 3 5 5
1 3
5 3
4 3
3 7
9 8
Sample Output
5
4
5
3
4
4
5
5
5
Hint
解释:如果奶牛A和奶牛B一样高,则可以出现A看到B,B又看到A的情况,如果奶牛A矮于奶牛B,则只可能出现奶牛A看到奶牛B,奶牛B不可能看到奶牛A。
Solution
这题仔细分析,可以发现是一个贪心。
设 F[i] 表示第 i 头奶牛的高度,首先把每个
F[i] 都赋成最高高度。对于两头相望的奶牛 l,r ,它们之间的奶牛高度都要 -1 ,以满足要求。
即:
F[i]=F[i]−1 (l+1≤i≤r−1)由于区间不重叠,此方法正确性显然。
由于赋值的次数不确定,可以不处理重复的区间,这样就不会超时了。
Code
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10001;
int tot;
int first[N],next[N],en[N];
int f[N];
inline int read()
{
int X=0,w=1; char ch=0;
while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
return X*w;
}
int main()
{
int n=read(),s=read(),t=read(),m=read();
for(int i=1;i<=n;i++) f[i]=t;
while(m--)
{
int x=read(),y=read();
if(x>y) swap(x,y);
next[++tot]=first[x];
first[x]=tot;
en[tot]=y;
}
for(int i=1;i<=n;i++)
for(int j=first[i],last=0;j;j=next[j])
if(en[j]!=last)
{
for(int k=i+1;k<en[j];k++) f[k]--;
last=en[j];
}
for(int i=1;i<=n;i++) printf("%d\n",f[i]);
return 0;
}