查错 CH Round #57 - Story of the OI Class

时间:2023-03-08 17:23:04
查错 CH Round #57 - Story of the OI Class

题目:http://ch.ezoj.tk/contest/CH%20Round%20%2357%20-%20Story%20of%20the%20OI%20Class/查错

题解:刚开始看见立马以为是 p1790拓扑编号,于是改了下输出就交了。。。

然后就爆零了。。。

仔细看题发现:

本题要求  尽早处理编号小的点

尽量使编号小的点最早被处理

难道不一样?

后来发现了 p1790的样例:

5 4

4 1

1 3

5 3

2 5

然后就明白了

对p1790来说,要想1号尽早被处理,第一次就得处理4

而本题要求处理顺序最小 那么第一次处理的必须得是2

然后就呵呵了

所以这两题的解法分别是:

本题:正向贪心,每次选取入度为0的且编号最小的点

p1790:反向贪心,反向建图,每次选取出度为0且编号最大的点

代码:(本题)

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 250000
#define maxm 500+100
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
int n,m,head[maxn],inp[maxn],ans[maxn],cnt;
struct edge{int go,next;}e[maxn];
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();m=read();
for1(i,m)
{
int x=read(),y=read();
e[i].go=y;e[i].next=head[x];head[x]=i;inp[y]++;
}
for1(i,n)if(!inp[i])q.push(i);
while(!q.empty())
{
int x=q.top();q.pop();ans[++cnt]=x;
for(int i=head[x],y;i;i=e[i].next)
{
inp[y=e[i].go]--;
if(!inp[y])q.push(y);
}
}
if(cnt<n)printf("OMG.\n");else for1(i,n)printf("%d ",ans[i]);
return ;
}

(p1790)

 var head,q,next,go,a,f,outp:array[..] of longint;
i,h,t,n,m,x,y,l,tot:longint;
function get:longint;
var i,k:longint;
begin
get:=a[];
a[]:=a[l];dec(l);
i:=;k:=;
while k<=l do
begin
if (k<l) and (a[k]<a[k+]) then inc(k);
if (a[]<a[k]) then begin a[i]:=a[k];i:=k;k:=k<<;end
else k:=l+;
end;
a[i]:=a[];
end;
procedure put(x:longint);
var i,k:longint;
begin
inc(l);
a[]:=x;
i:=l;k:=l>>;
while k>= do
begin
if a[]>a[k] then begin a[i]:=a[k];i:=k;k:=k>>;end
else k:=;
end;
a[i]:=x;
end;
procedure init;
begin
readln(n,m);
for i:= to m do
begin
readln(x,y);
go[i]:=x;
next[i]:=head[y];
head[y]:=i;
inc(outp[x]);
end;
end;
procedure main;
begin
h:=;t:=;
for i:= to n do
if outp[i]= then
put(i);
tot:=n;
while l<> do
begin
x:=get;
f[x]:=tot;dec(tot);
i:=head[x];
while i<> do
begin
y:=go[i];
dec(outp[y]);
if outp[y]= then put(y);
i:=next[i];
end;
end;
for i:= to n do write(f[i],' ');
end;
begin
init;
main;
end.