题目链接:http://codeforces.com/contest/883/problem/B

There are n military men in the Berland army. Some of them have given orders to other military men by now. Given m pairs (xiyi), meaning that the military man xi gave the i-th order to another military man yi.

It is time for reform! The Berland Ministry of Defence plans to introduce ranks in the Berland army. Each military man should be assigned a rank — integer number between 1 and k, inclusive. Some of them have been already assigned a rank, but the rest of them should get a rank soon.

Help the ministry to assign ranks to the rest of the army so that:

  • for each of m orders it is true that the rank of a person giving the order (military man xi) is strictly greater than the rank of a person receiving the order (military man yi);
  • for each rank from 1 to k there is at least one military man with this rank.
Input

The first line contains three integers nm and k (1 ≤ n ≤ 2·105, 0 ≤ m ≤ 2·105, 1 ≤ k ≤ 2·105) — number of military men in the Berland army, number of orders and number of ranks.

The second line contains n integers r1, r2, ..., rn, where ri > 0 (in this case 1 ≤ ri ≤ k) means that the i-th military man has been already assigned the rank riri = 0 means the i-th military man doesn't have a rank yet.

The following m lines contain orders one per line. Each order is described with a line containing two integers xiyi (1 ≤ xi, yi ≤ nxi ≠ yi). This line means that the i-th order was given by the military man xi to the military man yi. For each pair (x, y) of military men there could be several orders from x to y.

Output

Print n integers, where the i-th number is the rank of the i-th military man. If there are many solutions, print any of them.

If there is no solution, print the only number -1.

Examples
input
5 3 3
0 3 0 0 2
2 4
3 4
3 5
output
1 3 3 2 2 
input
7 6 5
0 4 5 4 1 0 0
6 1
3 6
3 1
7 5
7 1
7 4
output
2 4 5 4 1 3 5 
input
2 2 2
2 1
1 2
2 1
output
-1

题意为有n个士兵,现在要给他们赋军衔1-k,给m条边,每条边u->v表示u可以命令v,即u的军衔比v大。输出赋衔方案。
关键的要求:1.输入给定了一些士兵的军衔。只有部分士兵的军衔可供你修改。
      2.1-k这k个军衔每个都要有人。即对于任意一个军衔等级i,n个人中必须要有人获得这个军衔。 2真的是非常伤脑筋的一个要求。 最后队友想出了贪心:
先正反跑两次拓扑排序,
得到在考虑不考虑每个军衔情况下的,每个人的最高和最低可能军衔。 然后以最高可能军衔为第一关键字和最低可能军衔为第二关键字排序。
由于父亲的最高可能军衔一定比儿子大,所以父亲一定在前面。
然后贪心式地赋衔就可以了,注意一下如果第i个人的low等于目前贪心的top那么也要赋值为top就可以了。 AC代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=;
int n,m,k;
vector<int> head[MAXN];
vector<pair<int, int> > rnk[MAXN];
int solid[MAXN];
int low[MAXN],ans[MAXN];
int high[MAXN];
int in[MAXN];
int flag=;
struct Edge
{
int x,y;
Edge() {}
}edge[MAXN];
void Input()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;++i)
{
scanf("%d",&solid[i]);
}
int u,v;
for(int i=;i<=m;++i)
{
scanf("%d%d",&edge[i].x,&edge[i].y);
}
}
void init()
{
for(int i=;i<=n;++i)
{
head[i].clear();
in[i]=;
}
}
void toposort(int now[],int type)
{
queue<int > q;
int cnt=;
for(int i=;i<=n;++i)
{
if(!in[i])
{
q.push(i);
++cnt;
}
}
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=;i<head[u].size();++i)
{
int v=head[u][i];
if(type<)
{
now[v]=min(now[v],now[u]-);
}
else
{
now[v]=max(now[v],now[u]+);
}
if(--in[v]<=)
{
++cnt;
q.push(v);
}
}
}
if(cnt!=n)
{
flag=;
}
}
void work()
{
int u,v;
flag=;
init();
for(int i=;i<=n;++i)
{
if(solid[i]) high[i]=solid[i];
else high[i]=k;
}
for(int i=;i<=m;++i)
{
u=edge[i].x,v=edge[i].y;
head[u].push_back(v);
in[v]++;
}
toposort(high,-);
if(flag==)
{
printf("-1\n");
return;
}
init();
for(int i=;i<=n;++i)
{
if(solid[i]) low[i]=solid[i];
else low[i]=;
}
for(int i=;i<=m;++i)
{
u=edge[i].y;v=edge[i].x;
head[u].push_back(v);
in[v]++;
}
toposort(low,);
if(flag==)
{
printf("-1\n");
return;
} for(int i=;i<=n;++i)
{
if(low[i]>high[i])
{
printf("-1\n");return;
}
}
int top=k;
for(int i=;i<=k;++i) rnk[i].clear();
for(int i=;i<=n;++i)
{
rnk[high[i]].push_back(make_pair(-low[i],i));
}
set< pair<int,int> > S;
set< pair<int,int> >::iterator it;
for(int i=;i<rnk[k].size();++i)
{
S.insert(rnk[k][i]);
}
pair<int ,int > tmp;
while(top)
{
if(S.empty())
{
printf("-1\n");
return;
}
it=S.begin();
tmp=*it;
ans[tmp.second]=top;
S.erase(it);
while()
{
it=S.begin();
tmp=*it;
if(-tmp.first<top) break;
ans[tmp.second]=top;
S.erase(it);
}
--top;
for(int i=;i<rnk[top].size();++i)
{
S.insert(rnk[top][i]);
}
}
while(!S.empty())
{
tmp=*it;
ans[tmp.second]=;
S.erase(it);
}
for(int i=;i<=n;++i)
printf("%d ",ans[i]);
printf("\n");
}
int main()
{
// freopen("in.txt","r",stdin);
Input();
work();
return ;
}

2017-2018 ACM-ICPC NEERC B题Berland Army 拓扑排序+非常伤脑筋的要求的更多相关文章

  1. 【CF883B】Berland Army 拓扑排序

    [CF883B]Berland Army 题意:给出n个点,m条有向边,有的点的点权已知,其余的未知,点权都在1-k中.先希望你确定出所有点的点权,满足: 对于所有边a->b,a的点权>b ...

  2. 2018 ACM/ICPC 南京 I题 Magic Potion

    题解:最大流板题:增加两个源点,一个汇点.第一个源点到第二个源点连边,权为K,然后第一个源点再连其他点(英雄点)边权各为1,然后英雄和怪物之间按照所给连边(边权为1). 每个怪物连终点,边权为1: 参 ...

  3. 【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP

    [BZOJ5109][CodePlus 2017]大吉大利,晚上吃鸡! Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏 ...

  4. [ACM] hdu 1285 确定比赛名次 (拓扑排序)

    确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  5. 2017 ACM/ICPC 沈阳 K题 Rabbits

    Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number line, each occupying a ...

  6. 2017 ACM/ICPC 沈阳 L题 Tree

    Consider a un-rooted tree T which is not the biological significance of tree or plant, but a tree as ...

  7. 2017 ACM/ICPC 沈阳 I题 Little Boxes

    Little boxes on the hillside. Little boxes made of ticky-tacky. Little boxes. Little boxes. Little b ...

  8. 2017 ACM/ICPC 沈阳 G题 Infinite Fraction Path

    The ant Welly now dedicates himself to urban infrastructure. He came to the kingdom of numbers and s ...

  9. 2017 ACM/ICPC 沈阳 F题 Heron and his triangle

    A triangle is a Heron’s triangle if it satisfies that the side lengths of it are consecutive integer ...

随机推荐

  1. Nginx配置SSL证书实现https访问「浏览器未认证」

    http 和 https 介绍 http:应用最广泛的一种网络协议,是一个B/S的request和response的标准,用于从www服务器传输超文本到本地浏览器的传输协议. https:以安全为目标 ...

  2. 一、restful规范 二、CBV(View)源代码执行流程 三、drf框架安装和简单使用

    一.restful规范 ''' 它是一个规范,面向资源架构 十条规范 1.API与用户的通讯协议,总是使用HTTPs协议,确保了网络传输的安全性 2.域名 --https://api.example. ...

  3. Cmd Markdown 编辑阅读器

    我们理解您需要更便捷更高效的工具记录思想,整理笔记.知识,并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 -- 我们为记录思想和分享知识提供更专业的工具. 您可以使用 Cmd ...

  4. (转)A curated list of Artificial Intelligence (AI) courses, books, video lectures and papers

    A curated list of Artificial Intelligence (AI) courses, books, video lectures and papers. Updated 20 ...

  5. Static需谨慎

    Static Cling Sticking Your Code To Things Unnecessarily Static Cling is a code smell used to describ ...

  6. vi删除当前行的字符

    x 删除当前光标下的字符dw 删除光标之后的单词剩余部分.d$ 删除光标之后的该行剩余部分.dd 删除当前行

  7. Centos 6.8安装ideaIU-2017.2.6-no-jdk

    参考资料: (一)https://www.jetbrains.com/help/idea/2017.2/intellij-idea-help.pdf  (链接: https://pan.baidu.c ...

  8. 拼接字符串,生成tree格式的JSON数组

    之前做的执法文书的工作,现在需要从C#版本移植到网页版,从Thrift接口获取数据,加载到对应的控件中 之前用的easyui的Tree插件,通过<ul><li><span ...

  9. [原]编译flightGear

    参考:flightgear编译博客201705 flightGear是三维飞行仿真软件,这个款软件是开源的,我们尝试用其源码完整编译一遍这个工程,并使用它. 它用到里以下扩展库: 空气动力学库:JSB ...

  10. vue 模仿机票自定义日历组件,区间选择

    1.创建组件  components > calander > index.vue <template> <div class="page" v-if ...