solution-2022 CCPC Guilin J. Permutation Puzzle

题解:2022 CCPC 桂林站 J 题题解

模拟赛 T3 放了这道题人均场切了。我没删调试爆零了。

首先按所有限制连边 uivi。题目保证了这是一张有向无环图。

我们肯定是只能按照某种拓扑序来填。

有一个非常显然的策略是在拓扑排序中按照每个点的后继节点的最小值为第一关键字,更小的先填。

这非常符合直觉,也确实是对的。因为无论如何你都要在当前最小值之前到那。

#include<bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int mininf = 1e9 + 7;
#define int long long
#define pb emplace_back
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void write(int x){if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');}
#define put() putchar(' ')
#define endl puts("")
const int MAX = 2e5 + 10;
vector <int> g[MAX];
vector <int> g2[MAX];
bool vis[MAX];
int a[MAX];
void dfs(int u){
vis[u] = 1;
for(int v : g[u]){
if(!vis[v]) dfs(v);
a[u] = min(a[u], a[v]);
}
}
int deg[MAX];
int deg2[MAX];
int b[MAX];
int to[MAX];
bool fl[MAX];
void solve(){
int n = read(), m = read();
for(int i = 1; i <= n; i++)a[i] = b[i] = deg[i] = deg2[i] = vis[i] = to[i] = fl[i] = 0;
for(int i = 1; i <= n; i++)g[i].clear(),g2[i].clear();
for(int i = 1; i <= n; i++){
a[i] = read();
if(a[i] == 0) a[i] = inf;
else b[i] = a[i], to[a[i]] = i;
}
for(int i = 1; i <= m; i++){
int u = read(), v = read();
g[u].pb(v);
g2[v].pb(u);
deg[v]++;
deg2[u]++;
}
queue <int> que2;
for(int i = 1; i <= n; i++){
if(!deg2[i]) que2.push(i);
}
while(!que2.empty()){
int u = que2.front();
que2.pop();
for(int v : g2[u]){
deg2[v]--;
a[v] = min(a[v], a[u]);
if(!deg2[v]) que2.push(v);
}
}
// for(int i = 1; i <= n; i++){
// write(a[i]), put();
// }endl;
priority_queue <pair <int, int> > que;
// write(deg[13]), endl;
// for(int v : g[13]){
// write(a[v]), endl;
// }
for(int i = 1; i <= n; i++){
// if(b[i] == 700){
// write(a[13]), endl;
// for(int v : g2[i]) write(v), put();
// endl;
// }
if(!deg[i]){
if(b[i] == a[i]){
// if(b[i] == 700) puts("fjk");
// write(g[i] == 700) puts("kf");
fl[b[i]] = 1;
}else que.push(make_pair(-a[i], i));
}
}
// write(que.top().first), endl;
for(int i = 1; i <= n; i++){
if(to[i]){
if(!fl[i]){
// write(i), endl;
puts("-1");
for(int i = 1; i <= n; i++)a[i] = b[i] = deg[i] = deg2[i] = vis[i] = to[i] = fl[i] = 0;
for(int i = 1; i <= n; i++)g[i].clear(),g2[i].clear();
return ;
}
if(!que.empty() and -que.top().first <= i){
puts("-1");
for(int i = 1; i <= n; i++)a[i] = b[i] = deg[i] = deg2[i] = vis[i] = to[i] = fl[i] = 0;
for(int i = 1; i <= n; i++)g[i].clear(),g2[i].clear();
// write(i), put();
return ;
}
int u = to[i];
b[u] = i;
for(int v : g[u]){
deg[v]--;
if(!deg[v]){
if(a[v] == b[v]){
fl[b[v]] = 1;
}else{
que.push(make_pair(-a[v], v));
}
}
}
}else{
if(que.empty()) {
puts("-1");
for(int i = 1; i <= n; i++)a[i] = b[i] = deg[i] = deg2[i] = vis[i] = to[i] = fl[i] = 0;
for(int i = 1; i <= n; i++)g[i].clear(),g2[i].clear();
return ;
}
int u = que.top().second;
b[u] = i;
que.pop();
for(int v : g[u]){
deg[v]--;
if(!deg[v]){
if(a[v] == b[v]){
fl[b[v]] = 1;
}else{
que.push(make_pair(-a[v], v));
}
}
}
}
}
for(int i = 1; i <= n; i++){
write(b[i]), put();
}
endl;
}
signed main(){
// freopen("permutation.in", "r", stdin);
// freopen("permutation.out", "w", stdout);
int t = read();
while(t--) solve();
return 0;
}

本文作者:WRuperD

本文链接:https://www.cnblogs.com/WRuperD/p/18371659

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   WRuperD  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验

本文作者:DIVMonster

本文链接:https://www.cnblogs.com/guangzan/p/12886111.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

这是一条自定义内容

这是一条自定义内容

点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Imagine John Lennon
  2. 2 海阔天空 Beyond
  3. 3 Iridescent Linkin Park
  4. 4 New Devide Linkin Park
  5. 5 Bohemian Rhapsody Queen
  6. 6 夜的第七章 周杰伦
  7. 7 夜曲 (Live) 周杰伦
  8. 8 七里香 丐版
  9. 9 止战之殇 (Live) 周杰伦
  10. 10 We Are The World U.S.A. For Africa
  11. 11 So Far Away (Acoustic) Adam Christopher
Imagine - John Lennon
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

: John Lennon

: John Lennon

Imagine there's no heaven

It's easy if you try

No hell below us

Above us only sky

Imagine all the people

Living for today...

Imagine there's no countries

It isn't hard to do

Nothing to kill or die for

And no religion too

Imagine all the people

Living life in peace...

You may say I'm a dreamer

But I'm not the only one

I hope someday you'll join us

And the world will be as one.

Imagine no possessions

I wonder if you can

No need for greed or hunger

A brotherhood of man

Imagine all the people

Sharing all the world...

You may say I'm a dreamer

But I'm not the only one

I hope someday you'll join us

And the world will live as one.