【CF883B】Berland Army 拓扑排序
【CF883B】Berland Army
题意:给出n个点,m条有向边,有的点的点权已知,其余的未知,点权都在1-k中。先希望你确定出所有点的点权,满足:
对于所有边a->b,a的点权>b的点权
对于i=1..k,至少有一个点的点权为i
n,m,k<=100000
题解:像菜肴制作一样奇怪的拓扑排序题,直接上方法吧,不会证。
先正反跑两边拓扑排序,得出每个点点权的下界Li和上界Ri。
将所有点按上界从小到大排序,然后枚举权值i。将所有上界为i的点都扔到堆中,再从堆里取出下界最大的那个点,将其权值赋为i。再找出所有下界为i的点,将他们的权值也都赋为i即可。
#include <cstdio>
#include <cstring>
#include <utility>
#include <queue>
#include <vector>
#define mp(A,B) make_pair(A,B)
using namespace std;
const int maxn=200010;
typedef pair<int,int> pii;
int n,m,k,cnt,flag;
int to[maxn],nxt[maxn],head[maxn],pa[maxn],pb[maxn],v[maxn],L[maxn],R[maxn],d[maxn],ans[maxn];
vector<int> p[maxn];
vector<int>::iterator it;
queue<int> q;
priority_queue<pii> pq;
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline void add(int a,int b)
{
to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;
}
int main()
{
n=rd(),m=rd(),k=rd();
int i,u;
for(i=1;i<=n;i++)
{
v[i]=rd();
if(!v[i]) L[i]=1,R[i]=k;
else L[i]=R[i]=v[i];
}
memset(head,-1,sizeof(head)),cnt=0;
for(i=1;i<=m;i++) pa[i]=rd(),pb[i]=rd(),d[pb[i]]++,add(pa[i],pb[i]);
for(i=1;i<=n;i++) if(!d[i]) q.push(i);
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=nxt[i])
{
d[to[i]]--,R[to[i]]=min(R[to[i]],R[u]-1);
if(!d[to[i]]) q.push(to[i]);
}
}
for(i=1;i<=n;i++) if(d[i]) return puts("-1"),0;
memset(head,-1,sizeof(head)),cnt=0;
for(i=1;i<=m;i++) d[pa[i]]++,add(pb[i],pa[i]);
for(i=1;i<=n;i++) if(!d[i]) q.push(i);
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=nxt[i])
{
d[to[i]]--,L[to[i]]=max(L[to[i]],L[u]+1);
if(!d[to[i]]) q.push(to[i]);
}
}
for(i=1;i<=n;i++) if(d[i]||L[i]>R[i]) return puts("-1"),0;
for(i=1;i<=n;i++) p[R[i]].push_back(i);
for(i=k;i>=1;i--)
{
for(it=p[i].begin();it!=p[i].end();it++) pq.push(mp(L[*it],*it));
if(pq.empty()) return puts("-1"),0;
u=pq.top().second,pq.pop(),ans[u]=i;
while(!pq.empty())
{
u=pq.top().second;
if(L[u]<i) break;
pq.pop(),ans[u]=i;
}
}
for(i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}
【CF883B】Berland Army 拓扑排序的更多相关文章
- 2017-2018 ACM-ICPC NEERC B题Berland Army 拓扑排序+非常伤脑筋的要求
题目链接:http://codeforces.com/contest/883/problem/B There are n military men in the Berland army. Some ...
- Berland Army CodeForces - 883B (贪心,拓扑排序)
大意: n个点, 点$i$的等级为$r_i$, 只给出部分点的$r$值, $r_i$的范围为[1,k], 且[1,k]都至少有一个. 给定m条有向边, (x,y)表示$r[x]>r[y]$, 求 ...
- Codeforces Beta Round #29 (Div. 2, Codeforces format) C. Mail Stamps 离散化拓扑排序
C. Mail Stamps Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem ...
- 算法与数据结构(七) AOV网的拓扑排序
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
- 有向无环图的应用—AOV网 和 拓扑排序
有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...
- 【BZOJ-2938】病毒 Trie图 + 拓扑排序
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 609 Solved: 318[Submit][Status][Di ...
- BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...
- 图——拓扑排序(uva10305)
John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task i ...
- Java排序算法——拓扑排序
package graph; import java.util.LinkedList; import java.util.Queue; import thinkinjava.net.mindview. ...
随机推荐
- GridView动态添加列并判断绑定数据DataTable的列类型控制展示内容
此篇随笔是2013年根据项目需求开发记录的,不一定符合大众口味,只需了解开发思路,毕竟解决方案多种多样. 下面简单说说需求点吧: (1)通过下拉列表可以选择一个DataSet(数据集),一个DataS ...
- SSH上传和下载文件
备个份: 一,ssh上传文件 scp file username@hostIP:文件地址 例: [zhangy@BlackGhost ~]$ scp test.sql zhangying@192.16 ...
- JavaBridge
有的时候我们需要在PHP里调用JAVA平台封装好的jar包里的class类和方法 一般的做法是采用php-java-bridge做桥接 1.实现原理: 先打开java的一个监听端口,php调用java ...
- ExtJS中给Tree节点加click事件
第一种: 直接通过TreePanel中的Config Option中的listener来添加,代码如下: var TreePan = new Ext.tree.TreePanel({ id: 'Tre ...
- Bootstrap 各种进度条详解
一:默认的进度条 创建一个基本的进度条的步骤如下: 添加一个带有 class .progress 的 <div>. 接着,在上面的 <div> 内,添加一个带有 class . ...
- git push 问题汇总
Q:git push时卡死 这个问题找的快要放弃的时候... A: git config --global http.postBuffer [via] Q:git push 报错 Counting o ...
- Linux chmod和chown更改文件目录的所属者命令的用法
一.chown 命令 用途:更改文件的所有者或组.命令由单词change owner组合而成. 使用示例: 1,更改文件的所有者: chown jim program.c 文件 program.c 的 ...
- 【Java知识点专项练习】之 volatile 关键字的功能
volatile是java中的一个类型修饰符.它是被设计用来修饰被不同线程访问和修改的变量.如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器 失去大量优化的机会. ...
- read by other session 等待事件。
今天是2014-01-06,从今天开始,打算春节之前每天学习一个等待事件,今天就记录一下read by other session这个等待事件笔记. 什么是read by other session? ...
- 如何修改 VIM 制表符的空格数?
想修改一下编辑器vi里的制表符(Tab)的空格数.因为它默认的太长(默认是8个空格). 在网上搜到了这篇文章http://my.oschina.net/captaintheron/blog/515 ...