题目链接: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. 节约内存:Instagram的Redis实践(转)

    Instagram可以说是网拍App的始祖级应用,也是当前最火热的拍照App之一,Instagram的照片数量已经达到3亿,而在Instagram里,我们需要知道每一张照片的作者是谁,下面就是Inst ...

  2. spool例子

    set head offset echo offset feed offset heads offset pages 50000SET NEWPAGE NONEcolumn yesterday new ...

  3. Java并发系列之Synchronized

    每一个刚接触多线程并发编程的同学,当被问到,如果多个线程同时访问一段代码,发生并发的时候,应该怎么处理? 我相信闪现在脑海中的第一个解决方案就是用synchronized,用锁,让这段代码同一时间只能 ...

  4. freeswqitch odbc

    1.安装驱动 yum install unixODBC unixODBC-devel libtool-ltdl libtool-ltdl-devel -y yum install mysql-conn ...

  5. 关于乱码(MessyCode)问题

    乱码本质:读取二进制时采用的编码和最初将字符转成二进制时的编码不一致 编码时(得二进制数组时)不抛出异常,数据就不会被破坏 Java关于乱码(MessyCode)问题 Java使用的是Unicode编 ...

  6. Java this关键字 学习笔记

    前言: 这篇博文就是系统的学习一下Java中的this关键字,本人对this关键字的理解知识简单的停留在对  类的成员变量进行赋值,这次所以决定系统的体会一下this 关键字 转自:https://b ...

  7. _quick_response

    在线答题,抢答 `question` 题库 `correctAnswer` 正确答案(A,B,C,D) `answerA` 选项显示 `answerB`选项显示 `answerC` 选项显示 `ans ...

  8. 谈谈如何给下拉框option添加点击事件?

    我们在用到下拉列表框select时,需要对选中的<option>选项触发事件,其实<option>本身没有触发事件方法,我们只有在select里的onchange方法里触发. ...

  9. Codeforces 1107 E - Vasya and Binary String

    E - Vasya and Binary String 思路:区间dp + 记忆化搜索 转移方程看上一篇博客. 代码: #pragma GCC optimize(2) #pragma GCC opti ...

  10. hive新功能cube和rollup

    1.cube简称数据魔方,可以实现hive多个任意维度的查询,cube(a,b,c)则首先会对(a,b,c)进行group by,然后依次是(a,b),(a,c),(a),(b,c),(b),(c), ...