题目链接:

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. 高性能MySQL--创建高性能的索引

    关于MySQL的优化,相信很多人都听过这一条:避免使用select *来查找字段,而是要在select后面写上具体的字段. 那么这么做的原因相信大家都应该知道:减少数据量的传输. 但我要讲的是另外一个 ...

  2. Redis的特性以及优势(附官网)

    NoSQL:一类新出现的数据库(not only sql) 泛指非关系型的数据库 不支持SQL语法 存储结构跟传统关系型数据库中的那种关系表完全不同,nosql中存储的数据都是KV形式 NoSQL的世 ...

  3. sqoop import/export使用经验

    一.先创建一个小表(test_01)进行测试(主节点IP:169.254.109.130/oracle服务器IP:169.254.109.100) 1.测试连接oracle; sqoop list-t ...

  4. EAC 抓取CD为AAC文件

    下载EAC v1.3 下载FAAC 安装完EAC以后进入主界面,选菜单EAC->compression option,如图: 选User Defined Encoder,选择之前解压好的faac ...

  5. Oracle入门第六天(中)——SET运算符(交并差集)

    一.概述 1.SET运算符是什么 将多个查询用 SET 操作符连接组成一个新的查询 UNION/UNION ALL——并集 INTERSECT——交集 MINUS——差集(A\B=A中去掉B中也有的元 ...

  6. 20155206 《Java程序设计》实验三实验报告

    20155206 <Java程序设计>实验三实验报告 实验内容 Java敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 提交一: 提交二: 提交三: 提交四:

  7. 20155232 实验四 Android程序设计

    20155232 实验四 Android程序设计 一.实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局管理器的使用: 3.掌握 ...

  8. 20155323 第三次实验 敏捷开发与XP实践

    20155323 第三次实验 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器 ...

  9. 【转载】DXUT进阶

    原文:DXUT进阶 概要 这个指南涵盖了更多DXUT的高级应用. 这个指南里的大部分功能是可选的, 为了以最小的代价来增强你的应用程序. DXUT提供了一个简单的基于GUI系统的精灵和一个设备设置对话 ...

  10. day5 if while for

    .注意点: ctrl + n 自动补全 18行报错,直接定位18行 逻辑运算符and or not 复合赋值运算符 += .if-elif 判断星期几 猜拳游戏 .while循环 )3大执行流程 )什 ...