题目链接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. python 迭代器(转)

    迭代器 迭代器是在python2.2中被加入的,它为类序列对象提供了一个类序列的接口.有了迭代器可以迭代一个不是序列的对象,因为他表现出了序列的行为.当在python中使用for循环迭代一个对象时,调 ...

  2. 深入 理解char * ,char ** ,char a[ ] ,char *a[] 的区别(转)

    C语言中由于指针的灵活性,导致指针能代替数组使用,或者混合使用,这些导致了许多指针和数组的迷惑,因此,刻意再次深入探究了指针和数组这玩意儿,其他类型的数组比较简单,容易混淆的是字符数组和字符指针这两个 ...

  3. Linux 升级内核开启 TCP BBR 有多大好处

    前言 如果你有订阅一些科技新闻,应该会有看过内核在4.9当中加入了一个新的算法,来解决在有一定的丢包率的情况下的带宽稳定的问题,这个是谷歌为我们带来的干货,新的 TCP 拥塞控制算法 BBR (Bot ...

  4. Redis未授权访问漏洞复现与利用

    漏洞简介 Redis默认情况下,会绑定在0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等,这样将会将Redis服务暴露到公网上,如果在没有设置密码认 ...

  5. linux学习笔记全-如何学习linux?

    简介 今天整理文件整理出了好多年前学习linux的笔记 就整理下发布在博客上怕文件形式会误删. linux入门基础对于新手而言不推荐看书!!不推荐看书!!(大牛跳过)先看视频看linuxcast的视频 ...

  6. Guitar Pro教程之组织小节

    上一章节我们讲述了关于Guitar Pro 7的主界面的相关功能的介绍,对于初学作曲,又是吉他的初学者,刚刚接触{cms_selflink page='index' text='Guitar Pro' ...

  7. 免费在线使用Ayoa:让思维导图更简单

    在学习和工作中,我们都会遇到需要使用思维导图的情况,导图可以很好地帮助我们处理工作,完成记录和分享,是一个非常便捷的工具.今天小编就想和大家分享一款非常简单好用的思维导图软件,Ayoa. 之所以要将它 ...

  8. php form表单提交时,action url中参数无效的解决方法

    表单提交时get方式的一个错误 <form class="form-inline pull-right" method="get" action=&quo ...

  9. 剑指Offer_WEEK01

    剑指 Offer 03. 数组中重复的数字 思路:将数组进行排序,这样数组是一个有序的序列,然后判断两个相邻的数是否相等,是则返回相同的数 class Solution { public: int f ...

  10. NameServer 与zk

    1.nameServer 之间互不通信,故不存在强一致性,即不同的producer看到的视图可能时不一样的,(如何保证最终一致的?) 2.nameServer维护的boker信息 发生变化时,不会像z ...