bzoj4010: [HNOI2015]菜肴制作【拓扑排序】
想到了一个分治方法,每一次尽量放小的那个,把它依赖的放在左边,不依赖的放在右边。
TLE 80:
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define drep(i, a, b) for (int i = a; i >= b; i--)
#define REP(i, a, b) for (int i = a; i < b; i++)
#define mp make_pair
#define pb push_back
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second
using namespace std;
typedef long long i64;
typedef pair<int, int> pii;
const int inf = ~0U >> ;
const i64 INF = ~0ULL >> ;
//*********************************** const int maxn = ; vector <int> Vx[maxn], Vy[maxn];
int src[maxn], lft[maxn]; int n, m;
int deg[maxn], tmp[maxn]; bool topo() {
static int que[maxn]; int qh(), qt();
rep(i, , n) if (!deg[i]) que[++qt] = i;
int cnt();
while (qh != qt) {
int x = que[++qh];
++cnt;
int len = (int) Vx[x].size();
for (int i = ; i < len; i++) {
if (--deg[Vx[x][i]] == ) que[++qt] = Vx[x][i];
}
}
return cnt == n;
} bool vis[maxn];
void bfs(int s) {
static int que[maxn]; int qh(), qt();
vis[que[++qt] = s] = ;
while (qh != qt) {
int x = que[++qh];
int len = (int) Vy[x].size();
for (int i = ; i < len; i++) {
if (!vis[Vy[x][i]]) {
vis[que[++qt] = Vy[x][i]] = ;
lft[Vy[x][i]] = ;
}
}
}
} void solve(int l, int r) {
if (l >= r) return;
int t, haha = inf;
rep(i, l, r) if (src[i] < haha) { t = i; haha = src[i]; }
rep(i, l, r) lft[src[i]] = vis[src[i]] = ;
bfs(src[t]);
int cur = l - ;
rep(i, l, r) if (src[i] != src[t] && lft[src[i]]) tmp[++cur] = src[i];
tmp[++cur] = src[t]; int mid = cur;
rep(i, l, r) if (src[i] != src[t] && !lft[src[i]]) tmp[++cur] = src[i];
memcpy(src + l, tmp + l, sizeof(int) * (r - l + ));
solve(l, mid - );
solve(mid + , r);
} int main() {
freopen("dishes.in", "r", stdin);
freopen("dishes.out", "w", stdout);
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
rep(i, , n) Vx[i].clear(), Vy[i].clear();
clr(deg);
rep(i, , m) {
int x, y; scanf("%d%d", &x, &y);
Vx[x].pb(y);
Vy[y].pb(x);
deg[y]++;
}
if (!topo()) { puts("Impossible!"); continue; }
rep(i, , n) src[i] = i;
solve(, n);
rep(i, , n) printf(i == n ? "%d\n" : "%d ", src[i]);
}
return ;
}
正解:
有依赖关系,我们建立反图,加入我们的到了这个反图的一个拓扑序,那么怎样对应到最优的答案呢?应该是尽量让编号小的出现在队列后方,所以最大字典序的拓扑排序即可。
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define drep(i, a, b) for (int i = a; i >= b; i--)
#define REP(i, a, b) for (int i = a; i < b; i++)
#define mp make_pair
#define pb push_back
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second
using namespace std;
typedef long long i64;
typedef pair<int, int> pii;
const int inf = ~0U >> ;
const i64 INF = ~0ULL >> ;
//*********************************** const int maxn = ; vector <int> Vx[maxn], Vy[maxn];
priority_queue<int> Q;
int deg[maxn], ans[maxn], n, m; bool topo() {
rep(i, , n) if (!deg[i]) Q.push(i);
int cnt();
while (!Q.empty()) {
int x = Q.top(); Q.pop();
ans[++cnt] = x;
int len = (int) Vy[x].size();
for (int i = ; i < len; i++) {
if (--deg[Vy[x][i]] == ) Q.push(Vy[x][i]);
}
}
return cnt == n;
} int main() {
freopen("dishes.in", "r", stdin);
freopen("dishes.out", "w", stdout);
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
rep(i, , n) Vx[i].clear(), Vy[i].clear();
clr(deg);
rep(i, , m) {
int x, y; scanf("%d%d", &x, &y);
Vx[x].pb(y);
Vy[y].pb(x);
deg[x]++;
}
if (!topo()) puts("Impossible!");
else { drep(i, n, ) printf("%d ", ans[i]); puts(""); }
}
return ;
}
bzoj4010: [HNOI2015]菜肴制作【拓扑排序】的更多相关文章
- BZOJ4010[HNOI2015]菜肴制作——拓扑排序+堆
题目描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号为1.由于菜肴 ...
- BZOJ4010: [HNOI2015]菜肴制作(拓扑排序 贪心)
题意 题目链接 Sol 震惊,HNOI竟出NOI原题 直接在反图上贪心一下. // luogu-judger-enable-o2 // luogu-judger-enable-o2 #include& ...
- 【BZOJ4010】[HNOI2015]菜肴制作 拓扑排序
[BZOJ4010][HNOI2015]菜肴制作 Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高 ...
- bzoj 4010: [HNOI2015]菜肴制作 拓扑排序
题目链接: 题目 4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory Limit: 512 MB 问题描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴 ...
- 【bzoj4010】[HNOI2015]菜肴制作 拓扑排序+堆
题目描述 给你一张有向图,问:编号-位置序(即每个编号的位置对应的序列)最小(例如1优先出现在前面,1位置相同的2优先出现在前面,以此类推)的拓扑序是什么? 输入 第一行是一个正整数D,表示数据组数. ...
- [LOJ2114][HNOI2015]-菜肴制作-拓扑排序+贪心
<题面> 一个蒟蒻的痛苦一天 在今天的节目集训中,麦蒙将带领大家学习9种错误的解题策略 $15\%$算法(看两个就往下走吧) 1> puts("Impossible!&qu ...
- 洛谷P3243 [HNOI2015]菜肴制作 拓扑排序+贪心
正解:拓扑排序 解题报告: 传送门! 首先看到它这个约束就应该要想到拓扑排序辣QwQ 首先想到的应该是用优先队列代替队列,按照节点编号排序 然后也很容易被hack:<5,1> 正解应为5, ...
- 洛谷P3243 [HNOI2015]菜肴制作——拓扑排序
题目:https://www.luogu.org/problemnew/show/P3243 正向按字典序拓扑排序很容易发现是不对的,因为并不是序号小的一定先做: 但若让序号大的尽可能放在后面,则不会 ...
- 【luoguP3243】[HNOI2015]菜肴制作--拓扑排序
题目描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予1到N的顺序编号,预估质量最高的菜肴编号为1. 由于菜肴 ...
- [bzoj4010][HNOI2015]菜肴制作_贪心_拓扑排序
菜肴制作 bzoj-4010 HNOI-2015 题目大意:给定一张n个点m条边的有向图,求一个toposort,使得:(1)满足编号为1的点尽量在前:(2)满足(1)的情况下编号为2的点尽量在前,以 ...
随机推荐
- 求N以内与N互质的数的和
题目连接 /* 求所有小于N且与N不互质的数的和. 若:gcd(n,m)=1,那么gcd(n,n-m)=1; sum(n)=phi(n)*n/2; //sum(n)为小于n的所有与n互质的数的和 // ...
- sqlserver2008行锁
select * from tablename WITH (UPDLOCK) where Id=#value#
- MVVM 入门介绍
转载自:http://www.objccn.io/issue-13-1/ 我于 2011 年在 500px 找到自己的第一份 iOS 开发工作.虽然我已经在大学里做了好几年 iOS 外包开发,但这才是 ...
- Servlet程序开发--Servlet 与 表单
servlet程序: doPost方法时为了防止表单提交时post方式的问题.否则只能处理get请求 package org.lxh.servletdemo ; import java.io.* ; ...
- C# 中的内存管理,摘自网络
C#编程的一个优点是程序员不需要关心具体的内存管理,尤其是垃圾收集器会处理所有的内存清理工作.虽然不必手工管理内存,但如果要编写高质量的代码,还是要理解后台发生的事情,理解C#的内存管理.本文主要介绍 ...
- 修改smali文件,重打包,实现调用第三方SO文件
Java代码: static{ // //loadlibary里 要把SO文件名的lib和后缀去掉.libfgma.so --> fgma System.loadLibrary("fg ...
- openwrt串口的使用
从 RT5350 的芯片手册上可以得知, RT5350 一共有两个串口, 分别为 UART Lite. UART Full, UART Lite 就是我们惯称为的串口 1,作为系统调试串口,通过这个串 ...
- Android App监听软键盘按键的三种方式(转)
最近有类似需求,在csdn上刚好发现,粘贴过来,以防止忘记喽 前言: 我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“G ...
- Android里merge和include标签的使用
1.使用<include /> 标签来重用layout代码 如果在一个项目中需要用到相同的布局设计,可以通过<include /> 标签来重用layout代码,该标签在andr ...
- GPRS优点介绍及GPRS上网相关知识(转)
源:http://blog.chinaunix.net/uid-20745340-id-1878732.html 单片机微控制器以其体积小.功耗低.使用方便等特点,广泛应用于各种工业.民用的嵌入式系统 ...