HDU 5195 DZY Loves Topological Sorting (拓扑排序+线段树)
题目地址:HDU 5195
简直受不了了。。BC第二题都开始线段树+拓扑排序了。。。
这题很容易想到拓扑排序过程中贪心,但是贪心容易TLE,所以需要用数据结构去维护,我用的是线段树维护。每次找入度小于等于k的编号最大的点,这样就可以保证字典序一定是最大的。
代码如下:
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
#pragma comment(linker, "/STACK:1024000000")
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=100000+10;
int deg[MAXN], head[MAXN], cnt, c[MAXN], Min[MAXN<<2];
#define root 1, n, 1
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
vector<int>vec;
int k, n;
struct node {
int u, v, next;
} edge[MAXN];
void add(int u, int v)
{
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
memset(deg,0,sizeof(deg));
cnt=0;
}
void PushUp(int rt)
{
Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
}
void Update(int p, int x, int l, int r, int rt)
{
if(l==r){
Min[rt]=x;
return ;
}
int mid=l+r>>1;
if(p<=mid) Update(p,x,lson);
else Update(p,x,rson);
PushUp(rt);
}
int Query(int l, int r, int rt)
{
if(l==r) return l;
int mid=l+r>>1;
if(Min[rt<<1|1]<=k) return Query(rson);
return Query(lson);
}
void topo()
{
int i, j, id;
for(i=0;i<n;i++){
id=Query(root);
k-=deg[id];
deg[id]=INF;
Update(id,INF,root);
vec.push_back(id);
for(j=head[id];j!=-1;j=edge[j].next){
int v=edge[j].v;
deg[v]--;
Update(v,deg[v],root);
}
}
}
int main()
{
int m, i, j, u, v;
while(scanf("%d%d%d",&n,&m,&k)!=EOF) {
vec.clear();
init();
while(m--) {
scanf("%d%d",&u,&v);
deg[v]++;
add(u,v);
}
for(i=1;i<=n;i++){
Update(i,deg[i],root);
}
topo();
for(i=0; i<n; i++) {
printf("%d",vec[i]);
if(i!=n-1) printf(" ");
}
puts("");
}
return 0;
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。