HDU 5195 DZY Loves Topological Sorting 拓扑排序
2016-04-23 15:04
295 查看
题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5195bc(中文):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 + 10; const int INF = 0x3f3f3f3f; int n, m, k; struct Node { int v, flag; Node(int v,int flag=0):v(v),flag(flag){} Node() { flag = 0; } }; vector<Node> head[maxn]; int ind[maxn],done[maxn]; void init() { for (int i = 0; i < n; i++) { ind[i] = done[i]=0; head[i].clear(); } } int main() { while (scanf("%d%d%d", &n, &m, &k) == 3 && n) { init(); for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); u--, v--; ind[v]++; head[u].push_back(Node(v,0)); } priority_queue<int> pq; //删边 for (int i = n - 1; i >= 0; i--) { if (k >= ind[i]) { //将i的父亲ui中,满足ui<i,即边(ui,i)删了,这里要注意,对于边(ui,i),ui>i的边,根本不用删 k -= ind[i]; pq.push(i); for (int j = 0; j < head[i].size(); j++) { Node &nd = head[i][j]; if (i > nd.v) { //把边(i,v)删了,拓扑排序的时候不能再走这条边了 nd.flag = 1; 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] = 1; for (int i = 0; i < head[u].size(); i++) { Node& nd = head[u][i]; if (done[nd.v]||nd.flag) continue; ind[nd.v]--; if (ind[nd.v] == 0) pq.push(nd.v); } } printf("%d", ans[0]+1); for (int i = 1; i < ans.size(); i++) printf(" %d", ans[i]+1); printf("\n"); } return 0; } /* 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 + 10; const int INF = 0x3f3f3f3f; int n, m, k; vector<int> head[maxn]; int ind[maxn<<2],minv[maxn<<2]; 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 + 1, 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 + 1, r,res); else if (k >= minv[lson]) query(lson, l, M,res); } } void init() { for (int i = 1; i <= n; i++) head[i].clear(); memset(ind, 0, sizeof(ind)); memset(minv,0,sizeof(minv)); } int main() { while (scanf("%d%d%d", &n, &m, &k) == 3 && n) { init(); for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); head[u].push_back(v); _pos = v, _v = 1; update(1, 1, n); } //puts("after update"); vector<int> ans; for (int i = 0; i < n; i++) { int res; query(1, 1, n, res); //puts("after first qurey!"); //printf("res:%d\n", res); ans.push_back(res); for (int j = 0; j < head[res].size(); j++) { _pos = head[res][j], _v = -1; update(1, 1, n); //puts("after first upate"); } _pos = res, _v = INF; update(1, 1, n); } //puts("ans is zero"); printf("%d", ans[0]); for (int i = 1; i < ans.size(); i++) printf(" %d", ans[i]); printf("\n"); } return 0; }
相关文章推荐
- apache kafka总结
- 熟悉 Bash 快捷键来提高效率
- 为vultr(CentOS6.7)安装破解版锐速
- Hadoop2.6.0集群搭建
- Hadoop Shell命令
- Linux字符设备注册与注销
- java jsp实现网站访问量的统计
- Docker基础技术:DeviceMapper
- window server2012 + IIS8.0 + tomcat 集成环境搭建
- Docker基础技术:AUFS
- Docker基础技术:Linux CGroup
- Docker基础技术:Linux Namespace(下)
- Docker基础技术:Linux Namespace(上)
- 用 Tomcat 和 Eclipse 开发 Web 应用程序
- Linux 性能查看命令:
- tomcat 学习总结
- 学习总结 之 WebApi服务监控 log4net记录监控日志
- XManager远程图形界面登录centos
- Mac / Linux Shell 批量重命名的方法总览-[转]
- Kali linux 2016 rolling安装后的一些操作