【题解】G.Graph(2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest)
题目链接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)的更多相关文章
- Codeforces 2018-2019 ICPC, NEERC, Southern Subregional Contest
2018-2019 ICPC, NEERC, Southern Subregional Contest 闲谈: 被操哥和男神带飞的一场ACM,第一把做了这么多题,荣幸成为7题队,虽然比赛的时候频频出锅 ...
- 2018-2019 ICPC, NEERC, Southern Subregional Contest
目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Clou ...
- 模拟赛小结: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 ...
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest (9/12)
$$2015-2016\ ACM-ICPC,\ NEERC,\ Northern\ Subregional\ Contest$$ \(A.Alex\ Origami\ Squares\) 签到 //# ...
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D】---暑假三校训练
2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D Problem D. Distribution in Metagonia Input ...
- ACM ICPC 2016–2017, NEERC, Northern Subregional Contest Problem J. Java2016
题目来源:http://codeforces.com/group/aUVPeyEnI2/contest/229510 时间限制:2s 空间限制:256MB 题目大意: 给定一个数字c 用 " ...
- codeforce1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) 题解
秉承ACM团队合作的思想懒,这篇blog只有部分题解,剩余的请前往星感大神Star_Feel的blog食用(表示男神汉克斯更懒不屑于写我们分别代写了下...) C. Cloud Computing 扫 ...
- 2016 NEERC, Northern Subregional Contest G.Gangsters in Central City(LCA)
G.Gangsters in Central City 题意:一棵树,节点1为根,是水源.水顺着边流至叶子.该树的每个叶子上有房子.有q个询问,一种为房子u被强盗入侵,另一种为强盗撤离房子u.对于每个 ...
- Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结
第一次打ACM比赛,和yyf两个人一起搞事情 感觉被两个学长队暴打的好惨啊 然后我一直做傻子题,yyf一直在切神仙题 然后放一波题解(部分) A. Find a Number LINK 题目大意 给你 ...
随机推荐
- Maximum Subarray(最大连续子串)
1 class Solution { 2 public: 3 //动态规划,维护两个变量 local[i+1]=max(array[i],local[i]+array[i+1]) 4 int Find ...
- 45. 跳跃游戏 II
给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [2,3,1,1,4]输出 ...
- mysql权限管理命令
#创建用户 create user 'songwp' IDENTIFIED BY '1234' #用户授权 GRANT ALL ON DB01.* TO 'songwp' #撤销权限 REVOKE A ...
- 2w+长文带你剖析ConcurrentHashMap~!
并发编程实践中,ConcurrentHashMap是一个经常被使用的数据结构,相比于Hashtable以及Collections.synchronizedMap(),ConcurrentHashMap ...
- mysql之多表查询的其他查询
1,临时表查询 (1)需求:查询高于本部门平均工资的人员 select * from person as p, (select dept_id, avg(salary) as '平均工资' from ...
- 如何个性化定制iview中的table样式
使用renderHeader.render函数 例子: column:[ {}, ..., { title:'较年初占比变化', key:''lastYearChange, renderHeader: ...
- [原题复现]SUCTF 2019 WEB EasySQL(堆叠注入)
简介 原题复现: 1 <?php 2 session_start(); 3 4 include_once "config.php"; 5 6 $post = array() ...
- beef+metasploit
beef调用metasploit模块,直接xss吊打 先进入beef的文件夹 对config.yaml进行修改 将metasploit的false改为true 进入这个文件夹 修改配置文件 检查met ...
- zookeeper和kafka的leader和follower
来源于:https://www.cnblogs.com/aspirant/p/9179045.html 一.zookeeper 与kafka保持数据一致性的不同点: (1)zookeeper使用了ZA ...
- 在 Spark 数据导入中的一些实践细节
本文由合合信息大数据团队柳佳浩撰写 1.前言 图谱业务随着时间的推移愈发的复杂化,逐渐体现出了性能上的瓶颈:单机不足以支持更大的图谱.然而,从性能上来看,Neo4j 的原生图存储有着不可替代的性能优势 ...