题目链接G题

题意

序列 \(a_1,a_2,⋯,a_n\) 是一个排列, 当且仅当它含有 1 到 n 的所有整数。

排列 \(a_1,a_2,⋯,a_n\) 是一个有向图的拓扑排序,当且仅当对于每条边 \(u→v\),这个排列中 \(u\) 都出现在 \(v\) 之前。

给定一个有向无环图,添加至多 k 条有向边,使图保持无环,且字典序最小的拓扑排序字典序最大

思路

很有意思的一道构造题。

主要想法就是字典序较大的连边限制字典序小的。

两个堆:一个小根一个大根(小根堆是当前可以填写的节点集合,大根堆是已经分配了入边的集合)

拓扑序中,要填x,如果不填x,将要填的后面一个更大,(意味着不填x更优)那么将k条边中一条分配给x,入大根堆。但是还有一些不能入的情况:

如果 k为0 或者 小根堆siz=1 且 大根堆空或大根堆最大小于x,那么把x放入拓扑序,否则放到大根堆;

reason:k为0,没有边可以分配了

小根堆siz=1,是当前最后一个入度为0的点,如果加入边会出现环

如果是当前最后一个入度为0的点且没有点被加边,那么加边就是浪费,不如直接拓扑

如果是当前最后一个入度为0的点且比所有被加边的编号都要大,也是浪费(

如果小根堆空,那么把大根堆top放入拓扑序并且和拓扑序前一个连入边.

当一个点被放入拓扑序的时候,把所有指向的点入度--,如果为0,那么入小根堆。

这样就构成了一个系统:小根堆是可以放的点,大根堆是预备了一条边,但是不知道pre是谁的点。显然从任意一个点连边都是合法的。那么当不得不把这个点放进拓扑序的时候就选择其中最大的节点pop就好了(在前面的尽可能大)

(不知道为啥这道题过不了样例就AC……样例奇怪得很)

(注:如果你WA on test1了,把文件头加上再试一遍))

Code

采用set替代堆。

#include <bits/stdc++.h>
#define mp(x,y) make_pair(x,y)
using namespace std;
const int N=1e5+10;
set<int>pmax,pmin;
vector<pair<int,int> >edge;
vector<int>g[N];
int in[N],ord[N],n,m,k,cnt,pre; void topo( int x )
{
ord[++cnt]=x; pre=x;
for ( int i=g[x].size()-1; ~i; i-- )
{
int y=g[x][i];
if ( --in[y]==0 ) pmin.insert(y);
}
} int main()
{
freopen( "graph.in","r",stdin ); freopen( "graph.out","w",stdout ); scanf( "%d%d%d",&n,&m,&k );
for ( int i=1; i<=n; i++ )
g[i].clear(),in[i]=0;
for ( int i=1,u,v; i<=m; i++ )
scanf( "%d%d",&u,&v ),g[u].push_back(v),in[v]++; pmin.clear(); pmax.clear(); edge.clear();
for ( int i=1; i<=n; i++ )
if ( in[i]==0 ) pmin.insert(i);
pre=0; cnt=0;
while ( cnt<n )
{
if ( pmin.size()==0 ) //如果小根堆空,那么把大根堆top放入拓扑序并且和拓扑序前一个连入边
{
int x=*--pmax.end();
edge.push_back( mp(pre,x) );
topo(x); pmax.erase(x);
}
else if ( !k || pmin.size()==1 && (pmax.size()==0 || *pmin.begin()>*--pmax.end()) )
{
int x=*pmin.begin(); topo(x); pmin.erase(x);
} //如果 k为0 或者 小根堆=1 且 大根堆空或大根堆最大小于x,那么把x放入拓扑序
else //否则放入大根堆
{
k--; int x=*pmin.begin();
pmin.erase(x); pmax.insert(x);
}
}
for ( int i=1; i<=cnt; i++ )
printf( "%d ",ord[i] );
printf( "\n%d\n",edge.size() );
for ( int i=0; i<edge.size(); i++ )
printf( "%d %d\n",edge[i].first,edge[i].second );
}

【题解】G.Graph(2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest)的更多相关文章

  1. Codeforces 2018-2019 ICPC, NEERC, Southern Subregional Contest

    2018-2019 ICPC, NEERC, Southern Subregional Contest 闲谈: 被操哥和男神带飞的一场ACM,第一把做了这么多题,荣幸成为7题队,虽然比赛的时候频频出锅 ...

  2. 2018-2019 ICPC, NEERC, Southern Subregional Contest

    目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Clou ...

  3. 模拟赛小结:2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest

    2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest 2019年10月11日 15:35-20:35(Solved 8,Penalty 675 ...

  4. 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest (9/12)

    $$2015-2016\ ACM-ICPC,\ NEERC,\ Northern\ Subregional\ Contest$$ \(A.Alex\ Origami\ Squares\) 签到 //# ...

  5. 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D】---暑假三校训练

    2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D Problem D. Distribution in Metagonia Input ...

  6. ACM ICPC 2016–2017, NEERC, Northern Subregional Contest Problem J. Java2016

    题目来源:http://codeforces.com/group/aUVPeyEnI2/contest/229510 时间限制:2s 空间限制:256MB 题目大意: 给定一个数字c 用 " ...

  7. codeforce1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) 题解

    秉承ACM团队合作的思想懒,这篇blog只有部分题解,剩余的请前往星感大神Star_Feel的blog食用(表示男神汉克斯更懒不屑于写我们分别代写了下...) C. Cloud Computing 扫 ...

  8. 2016 NEERC, Northern Subregional Contest G.Gangsters in Central City(LCA)

    G.Gangsters in Central City 题意:一棵树,节点1为根,是水源.水顺着边流至叶子.该树的每个叶子上有房子.有q个询问,一种为房子u被强盗入侵,另一种为强盗撤离房子u.对于每个 ...

  9. Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结

    第一次打ACM比赛,和yyf两个人一起搞事情 感觉被两个学长队暴打的好惨啊 然后我一直做傻子题,yyf一直在切神仙题 然后放一波题解(部分) A. Find a Number LINK 题目大意 给你 ...

随机推荐

  1. IP 层收发报文简要剖析4--ip 报文发送

    无论是从本地输出的数据还是转发的数据报文,经过路由后都要输出到网络设备,而输出到网络设备的接口就是dst_output(output)函数 路由的时候,dst_output函数设置为ip_output ...

  2. 消失的两个数字(1-N缺两个数)

    给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字.你能在 O(N) 时间内只用 O(1) 的空间找到它们吗? 以任意顺序返回这两个数字均可. 示例 1: 输入: [1]输出: [2,3 ...

  3. phpstudy2016-2018漏洞验证

    影响版本 漏洞验证 查看目录下 php_xmlrpc.dll PHPTutorial\php\php-5.4.45\ext\php_xmlrpc.dll存在@eval(%s('%s'));即说明有后门 ...

  4. Spring源码之Bean生命周期

    https://www.jianshu.com/p/1dec08d290c1 https://www.cnblogs.com/zrtqsk/p/3735273.html 总结 将class文件加载成B ...

  5. nginx状态监控统计

    nginx是一款很优秀的web服务器软件,很多地方都有接触和使用到他,大部分的场景压力还没达到需要调优的地步,而调优的难点其实不在于调,而在于各项状态的监控,能够很快的找到资源在什么时候出现问题,调整 ...

  6. p5.js基本[一] T型高斯分布的小星星

    样例 <script src="./p5/p5.js"></script> <script> function setup() { // 只写一 ...

  7. API的使用(3)Arrays 类,Math类,三大特性--继承

    Arrays类 概述   java.util.Arrays此时主要是用来操作数组,里面提供了很多的操作API的方法.如[排序]和[搜索]功能.其所有的方法均为静态方法,调用起来非常简单. 操作数组的方 ...

  8. 玩转 Comparator 和 Comparable 两接口

    最近项目中有排序的需求,就查看了一下Java文档,发现有两个接口都可以进行排序,Comparable 和 Comparator 两接口到底有啥区别?何时用?怎么用?使用场景我都在底下一一研究分享出来: ...

  9. 真的可惜,四面阿里,结果我被JVM垃圾回收机制与 OOM异常卡住了

    前言 为什么需要垃圾回收 首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子 我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫, ...

  10. uniapp和vue 父向子传值、传方法及子向父传值。(一看就会超级简约)

    1.父向子传值:父组件在引用子组件时通过自定义属性绑定自身需要传递的值(数据),子组件用props:[  '自定义'  ]接收即可使用(props里数据是只读模式).(简约版:子绑定父的属性并用pro ...