题目链接: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. Java字节码浅析(二)

    英文原文链接,译文链接,原文作者:James Bloom,译者:有孚 条件语句 像if-else, switch这样的流程控制的条件语句,是通过用一条指令来进行两个值的比较,然后根据结果跳转到另一条字 ...

  2. MapReduce编程:平均成绩

    问题描述 现在有三个文件分别代表学生的各科成绩,编程求各位同学的平均成绩.                     编程思想 map函数将姓名作为key,成绩作为value输出,reduce根据key ...

  3. nmon 性能监控网页结果显示——EasyNmon

    首先,看看最终展示的结果显示样式: 报告界面: 1.安装包下载地址:https://github.com/mzky/easyNmon 2.下载后有2个压缩文件: 其中,nmon16g_x86中含有不同 ...

  4. [Hibernate] 通过 properties 类和 hql 语句进行动态查询

    //需要保证Emp和EmpProperties中的setter和getter以及属性以及 参数占位符(:eName) 的一致//动态查询 @Test public void test4(){ EmpP ...

  5. faker 模块

    faker是python的一个第三方模块,是一个github上的开源项目. 主要用来创建一些测试用的随机数据 文档:https://faker.readthedocs.io/en/master/ind ...

  6. JAVA多线程 总结

    1. Thread 和 Runnable java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行,由于线程类本身就是调用的Runnable接 ...

  7. leetcode-956. 最高的广告牌

    https://leetcode-cn.com/contest/weekly-contest-114/problems/tallest-billboard/ 给出一个集合,询问能否挑出两个不重叠的子集 ...

  8. SQL注入理解与防御

    一.说明 sql注入可能是很多学习渗透测试的人接触的第一类漏洞,这很正常因为sql注入可能是web最经典的漏洞.但在很多教程中有的只讲‘或and 1=1.and 1=2有的可能会进一步讲union s ...

  9. STL 小白学习(3) vector

    #include <iostream> using namespace std; #include <vector> void printVector(vector<in ...

  10. 学习笔记——SM2算法原理及实现

    RSA算法的危机在于其存在亚指数算法,对ECC算法而言一般没有亚指数攻击算法 SM2椭圆曲线公钥密码算法:我国自主知识产权的商用密码算法,是ECC(Elliptic Curve Cryptosyste ...