您的位置:首页 > 运维架构

【Best Coder】#35 DZY Loves Topological Sorting(线段树维护)

2015-03-29 23:00 429 查看
题目思路:题目要求点数最大的优先输出。由于可以将k条边去掉。

所以这边的一个基本思想就是。面对这次的输出。我们应该选择一个点数最大的,并且他的入度<=k即可。

并且注意是每次。每次都得重新选择。

下面这组数组就会让你懂得

5 3 2

4 5

3 5

1 5

答案应该是 4 5 3 2 1

所以这边需要实时更新每个点的入度,并且每次选择最大的那个入度小于k的那个点,正好利用线段树的维护和查询功能

AC代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 100005
#define ls rt<<1
#define rs ls|1
#define m (l+r)>>1
int sum[MAX << 2];
int head[MAX];
int in[MAX];
int cnt = 0;
int ans[100005];
struct pos
{
int v, next;
}p[MAX];

void addedge(int u, int v)
{
p[cnt].v = v;
p[cnt].next = head[u];
head[u] = cnt++;
}

void uprt(int rt)
{
sum[rt] = min(sum[ls], sum[rs]);
}

void build(int l, int r,int rt)
{
if (l == r)
{
sum[rt] = in[l];
return;
}
int mid = m;
build(l, mid, ls);
build(mid + 1, r, rs);
uprt(rt);
}

void updata(int q, int val,int l, int r, int rt)
{
if (l == r)
{
sum[rt] = val;
return;
}
int mid = m;
if (q<=mid)
updata(q, val, l, mid, ls);
else
updata(q, val, mid + 1, r, rs);
uprt(rt);
}

int get(int val, int l, int r, int rt)
{
if (l == r)
return l;
int mid = m;
if (val >=sum[rs])
return get(val, mid + 1, r, rs);
return get(val, l, mid, ls);
}
int main()
{
int n, k, q;
while (~scanf("%d%d%d", &n, &k, &q))
{
memset(head, -1, sizeof(head));
memset(in, 0, sizeof(in));
cnt = 0;
int a, b;
while (k--)
{
scanf("%d%d", &a, &b);
addedge(a, b);
in[b]++;
}
build(1, n, 1);
for (int i = 0; i < n; i++)
{
int res = get(q, 1, n, 1);
ans[i] = res;
q-= in[res];
in[res] = 0x7ffffff;
updata(res, in[res], 1, n, 1);
for (int i = head[res]; i != -1; i = p[i].next)
{
in[p[i].v]--;
updata(p[i].v, in[p[i].v], 1, n, 1);
}
}
printf("%d", ans[0]);
for (int i = 1; i < n; i++)
printf(" %d", ans[i]);
puts("");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: