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 of them have given orders to other military men by now. Given m pairs (xi, yi), 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.
The first line contains three integers n, m 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 ri; ri = 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 xi, yi (1 ≤ xi, yi ≤ n, xi ≠ 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.
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.
5 3 3
0 3 0 0 2
2 4
3 4
3 5
1 3 3 2 2
7 6 5
0 4 5 4 1 0 0
6 1
3 6
3 1
7 5
7 1
7 4
2 4 5 4 1 3 5
2 2 2
2 1
1 2
2 1
-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 拓扑排序+非常伤脑筋的要求的更多相关文章
- 【CF883B】Berland Army 拓扑排序
[CF883B]Berland Army 题意:给出n个点,m条有向边,有的点的点权已知,其余的未知,点权都在1-k中.先希望你确定出所有点的点权,满足: 对于所有边a->b,a的点权>b ...
- 2018 ACM/ICPC 南京 I题 Magic Potion
题解:最大流板题:增加两个源点,一个汇点.第一个源点到第二个源点连边,权为K,然后第一个源点再连其他点(英雄点)边权各为1,然后英雄和怪物之间按照所给连边(边权为1). 每个怪物连终点,边权为1: 参 ...
- 【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP
[BZOJ5109][CodePlus 2017]大吉大利,晚上吃鸡! Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏 ...
- [ACM] hdu 1285 确定比赛名次 (拓扑排序)
确定比赛名次 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 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 ...
- 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 ...
- 2017 ACM/ICPC 沈阳 I题 Little Boxes
Little boxes on the hillside. Little boxes made of ticky-tacky. Little boxes. Little boxes. Little b ...
- 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 ...
- 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 ...
随机推荐
- Python 简单soket例子
简单的soket例子 Python 2.0 客户端服务端传输 1.可发字符串,可发字节 bys类型 Python 3.0 客户端服务端传输 1.只能发bys,比特流的类型. 2.bys类型只能接收 ...
- 剑指offer(21)栈的压入、弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序 ...
- 【Git】vs code+git 不使用ssh的链接remote server的方式
git config --global user.name "dennis wu" git config --global user.email "email" ...
- 命令行找不到genstrings问题tip
问题:初次使用命令行genstrings,提示使用的是命令行工具而非xcode,无法直接使用genstrings. 解决方案:命令行输入sudo xcode-select --switch /Appl ...
- IdentityServer4中Code/Token/IdToken对应可访问的资源(api/identity)
{ OidcConstants.ResponseTypes.Code, ScopeRequirement.None }, { OidcConstants.ResponseTypes.Token, Sc ...
- cocos2d-js 小知识
由于自己是小白,决定把零碎的cocos2d-js知识记下来. 1. 列表容器listView,去掉滚动条 _listView.setScrollBarEnabled(false); 2. escap ...
- 关于input输入框内设置小图标的问题
其实很简单,只需要html和css就可以搞定啦 首先:<input class="layui-input" id="test1" placeholder= ...
- Django 编写模板并渲染的示例
>>> from django.template import Template, Context >>> raw_template = ""& ...
- POJ-3294 Life Forms n个字符串中出现超过n/2次的最长子串(按字典序依次输出)
按照以前两个字符串找两者的最长公共子串的思路类似,可以把所有串拼接到一起,这里为了避免讨论LCP跨越多个串需需要特别处理的问题用不同的字符把所有串隔开(因为char只有128位,和可能不够用,更推荐设 ...
- python内置类型:列表,包括 list 和 tuple
列表list 是一种有序的集合 ,假定list的名字为class list的元素个数:len( class) 访问元素: a. 索引从0开始 b. 也可以使用[-1],[-2],[-3] 从后面 ...