题目链接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. 什么是低代码(Low-Code)?

    阿里云 云原生应用研发平台EMAS 彭群(楚衡) 一.前言 如果选择用一个关键词来代表即将过去的2020年,我相信所有人都会认同是"新冠".疫情来得太快就像龙卷风,短短数月就阻断了 ...

  2. Dance Dance Revolution

    今天我们来讲 Dance Dance Revolution这题 本题原网址 注意本题为多组输入输出,直到输入单个零而止(题面有点小问题) 很明显,此题为一道动态规划题(请不要妄想用贪心算法过这题,尽管 ...

  3. C#高级编程之泛型三(协变与逆变)

    为何引入协变.逆变 我们知道一个子类对象可以赋值给一个基类对象 Animal animal = new Animal(); Animal cat = new Cat(); 那如果是用在泛型里面能行嘛? ...

  4. Unity CommandBuffer物体轮廓

    1.command buffer具有很高的灵活性,它的作用是预定义一些渲染指令,然后在我们想要执行的时候去执行这些指令(见图1),绿点表示可以在"Forward Rendering Path ...

  5. 免费|申请谷歌云服务器|msf安装

    apt-get install -y wget 参考链接 知乎-免费|申请谷歌云服务器 知乎-免费|申请谷歌云服务器 cnblogs-debian.ubuntu安装metasploit通用方法 谷歌云 ...

  6. Android系统添加key和keypad

    平台:MTK 一.添加一个按键 1.在DCT tool keypad list 文件增加新按键的选项alps\mediatek\source\dct\Keypad_YuSu.cmp中添加新键,如SMS ...

  7. guitar pro 系列教程(十八):Guitar Pro怎么设置吉他谱的局部速度?

    关于Guitar Pro的使用功能我们在前面的文章也有讲了不少,对于新手的小伙伴,就小编个人而言,在吉他编曲,演绎方面遇到的困难不是一点两点,我们只有通过学习了解他的全部,才能在以后的吉他创作中得心印 ...

  8. Windows启用SSH命令

    前言 直接通过windows自带的CMD终端远程连接服务器,需要先安装好OpenSSH客户端. 安装 使用浏览器打开官网: https://www.mls-software.com/opensshd. ...

  9. ?.可选链操作符( ?. ) 可选链运算符可防止抛出 TypeError: Cannot read property ’xxx' of undefined。

    可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效.?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null ...

  10. CF1156D 0-1-Tree

    路径考虑顺序. 显然合法的路径只有以下两种: 一段 \(0\) 加一段 \(1\) 或一段 \(1\) 加一段 \(0\). 全 \(0\) 或全 \(1\). 用并查集将边权为 \(0\) 和 \( ...