题目链接:

hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5195

bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=573&pid=1002

题解:

1、拓扑排序+贪心

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std; const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f; int n, m, k; struct Node {
int v, flag;
Node(int v,int flag=):v(v),flag(flag){}
Node() { flag = ; }
}; vector<Node> head[maxn];
int ind[maxn],done[maxn]; void init() {
for (int i = ; i < n; i++) {
ind[i] = done[i]=;
head[i].clear();
}
} int main() {
while (scanf("%d%d%d", &n, &m, &k) == && n) {
init();
for (int i = ; i < m; i++) {
int u, v;
scanf("%d%d", &u, &v); u--, v--;
ind[v]++;
head[u].push_back(Node(v,));
} priority_queue<int> pq; //删边
for (int i = n - ; i >= ; i--) {
if (k >= ind[i]) {
//将i的父亲ui中,满足ui<i,即边(ui,i)删了,这里要注意,对于边(ui,i),ui>i的边,根本不用删
k -= ind[i];
pq.push(i);
for (int j = ; j < head[i].size(); j++) {
Node &nd = head[i][j];
if (i > nd.v) {
//把边(i,v)删了,拓扑排序的时候不能再走这条边了
nd.flag = ;
ind[nd.v]--;
}
}
}
} vector<int> ans;
//拓扑排序
while (!pq.empty()) {
int u = pq.top(); pq.pop();
if (done[u]) continue;
ans.push_back(u);
done[u] = ;
for (int i = ; i < head[u].size(); i++) {
Node& nd = head[u][i];
if (done[nd.v]||nd.flag) continue;
ind[nd.v]--;
if (ind[nd.v] == ) pq.push(nd.v);
}
} printf("%d", ans[]+);
for (int i = ; i < ans.size(); i++) printf(" %d", ans[i]+);
printf("\n");
}
return ;
}
/*
5 3 1
4 3
1 3
3 2 5 3 0
4 3
1 3
3 2
*/

2、线段树+贪心

对于节点i,入度为ind[i],则可以这样贪心:对于1<=i<=n,求最大的i使得ind[i]<=k,我们可以把入度数组做成线段树,维护最小入度,二分查找,优先搜右边(右边的i会更大),找到以后,吧对于的子节点vj的入度减1,k-=ind[i]。这样一直做n次就能得到答案。

 #include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define lson (o<<1)
#define rson ((o<<1)+1)
#define M (l+(r-l)/2)
using namespace std; const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f; int n, m, k; vector<int> head[maxn];
int ind[maxn<<],minv[maxn<<]; int _pos, _v;
void update(int o, int l, int r) {
if (l==r) {
ind[o] += _v;
minv[o] = ind[o];
}
else {
if (_pos <= M) update(lson, l, M);
else update(rson, M + , r);
minv[o] = min(minv[lson], minv[rson]);
}
} void query(int o, int l, int r,int &res) {
if (l == r) {
if (ind[o] <= k) {
k -= ind[o];
res = l;
}
}
else {
//printf("lson:%d,rson:%d\n",minv[lson],minv[rson]);
if (k >= minv[rson]) query(rson, M + , r,res);
else if (k >= minv[lson]) query(lson, l, M,res);
}
} void init() {
for (int i = ; i <= n; i++) head[i].clear();
memset(ind, , sizeof(ind));
memset(minv,,sizeof(minv));
} int main() {
while (scanf("%d%d%d", &n, &m, &k) == && n) {
init();
for (int i = ; i < m; i++) {
int u, v;
scanf("%d%d", &u, &v);
head[u].push_back(v);
_pos = v, _v = ;
update(, , n);
}
//puts("after update");
vector<int> ans;
for (int i = ; i < n; i++) {
int res;
query(, , n, res);
//puts("after first qurey!");
//printf("res:%d\n", res);
ans.push_back(res);
for (int j = ; j < head[res].size(); j++) {
_pos = head[res][j], _v = -;
update(, , n);
//puts("after first upate");
}
_pos = res, _v = INF;
update(, , n);
}
//puts("ans is zero");
printf("%d", ans[]);
for (int i = ; i < ans.size(); i++) printf(" %d", ans[i]);
printf("\n");
}
return ;
}

HDU 5195 DZY Loves Topological Sorting 拓扑排序的更多相关文章

  1. hdu.5195.DZY Loves Topological Sorting(topo排序 && 贪心)

    DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  2. hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

    传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131 ...

  3. hdu 5195 DZY Loves Topological Sorting 线段树+拓扑排序

    DZY Loves Topological Sorting Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...

  4. hdu 5195 DZY Loves Topological Sorting (拓扑排序+线段树)

    DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  5. HDU 5195 - DZY Loves Topological Sorting

    题意: 删去K条边,使拓扑排序后序列字典序最大 分析: 因为我们要求最后的拓扑序列字典序最大,所以一定要贪心地将标号越大的点越早入队.我们定义点i的入度为di. 假设当前还能删去k条边,那么我们一定会 ...

  6. Topological Sorting拓扑排序

    定义: Topological Sorting is a method of arranging the vertices in a directed acyclic graph (DAG有向无环图) ...

  7. 2019.01.22 hdu5195 DZY Loves Topological Sorting(贪心+线段树)

    传送门 题意简述:给出一张DAGDAGDAG,要求删去不超过kkk条边问最后拓扑序的最大字典序是多少. 思路:贪心帮当前不超过删边上限且权值最大的点删边,用线段树维护一下每个点的入度来支持查询即可. ...

  8. 数据结构(线段树):HDU 5649 DZY Loves Sorting

    DZY Loves Sorting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Oth ...

  9. HDU 5649.DZY Loves Sorting-线段树+二分-当前第k个位置的数

    DZY Loves Sorting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Oth ...

随机推荐

  1. [译]C语言实现一个简易的Hash table(1)

    说明 Hash table翻译过来就是Hash表,是一种提供了类似于关联数组的数据结构,可以通过key执行搜索.插入和删除操作.Hash表由一些列桶(buckets)组成,而每一个bucket都是由k ...

  2. 100-Days-Of-ML-Code 评注版(Day 2)

    Day2_Simple_Linear_Regression(一元线性回归) 本文引用自 Simple Linear Regression, 对其中内容进行了评注与补充说明. 回归分析是一种预测性的建模 ...

  3. PCB布线设计(1)

    在PCB设计的时候,初学的时候对布线设计一无所知,那个时候老师布置  AT91SAM7X-开发板 作为学习例板  ,最终采用自动布线的结果如下 也并非全为自动布线,自动布线对于这种元器件稍多的很难全部 ...

  4. Java 多线程 volitile 和 atomic

    Java 多线程 volitile 和 atomic volitile关键字 public class MTester { public static class TestKey{ int x = 0 ...

  5. 笔记(assert 断言)

    并发:在同一个时间段交替执行多个任务并行:在同一个时间点同时执行多个任务串行:同时执行的多个任务按顺序执行(换句话说就是一个任务执行完后才能执行下一个任务) #mysql limit用法: selec ...

  6. ie的盒模型和标准模型

    使用 box-sizing:content-box || border-box || inherit 原理图 计算 怪异模型|IE模型 div宽度(定死) = 内容宽度+border宽度+paddin ...

  7. css3动画性能优化--针对移动端卡顿问题

    一.使用css,jquery,canvas制作动画 1.Canvas 优点:性能好,强大,支持多数浏览器(除了IE6.IE7.IE8),画出来的图形可以直接保存为 .png 或者 .jpg的图形: 缺 ...

  8. HTML5 学习笔记 | LOADING...

    一.HTML5基础知识 1.1 属性规范 1)元素应当合理嵌套 2)属性最好使用““包括 3)大小写不区分 1.2 常用html5标签 1)<!DOCTYPE> 定义文档类型 2)< ...

  9. Mybash实现

    Mybash实现 知识储备: feof是C语言标准库函数,其原型在stdio.h中,其功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返回0,文件结束符只能被clearerr()清除. 创 ...

  10. 20155229 2016-2017-2 《Java程序设计》第四周学习总结

    20155229 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 第六章: extends:继承某个类,继承之后可以使用父类的方法,也可以重写父类的方法,只要 ...