码迷,mamicode.com
首页 > 编程语言 > 详细

[AGC010E] Rearranging [拓扑排序+堆]

时间:2018-08-14 17:08:44      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:操作   char   define   href   ice   etc   push   fine   operator   

题面

传送门

思路

首先,一个显然的结论是:Alice调整过后的序列中任意两个不互质的数的相对顺序无法改变

那么我们可以以这个性质为突破口

我们在两个不互质的权值的点之间连一条边(没错这是个图论题!!!),那么每个联通块的一个拓扑序就会是这个块最终被Bob变成的样子

显然,Alice可以贪心操作,使得这个拓扑序中越小的越靠前

那么我们把所有数从小到大排序,然后从小的开始dfs,每次dfs时从最小的开始先走,得到一个$DAG$

然后把所有的$DAG$的拓扑排序的那个队列插到一个堆里面,每次取出最小的,就是Bob得到的序列的当前这一位

(相当于是并行做拓扑排序啦)

Code

给给全真给给

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
#include<queue>
#define ll long long
using namespace std;
inline int read(){
    int re=0,flag=1;char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') flag=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    return re*flag;
}
int n,g[2010][2010],a[2010],vis[2010],in[2010];
int first[2010],cnte;
struct edge{
    int to,next;
}e[10010];
inline void add(int u,int v){
    e[++cnte]=(edge){v,first[u]};first[u]=cnte;in[v]++;
}
int gcd(int x,int y){
    if(y==0) return x;
    return gcd(y,x%y);
}
void dfs(int u){
    vis[u]=1;int i;
    for(i=1;i<=n;i++){
        if(!vis[i]&&!g[u][i]) add(u,i),dfs(i);
    }
}
struct gaygayquan{
    int val,id;
};
inline bool operator <(gaygayquan x,gaygayquan b){
    return x.val<b.val;
}
gaygayquan mp(int l,int r){
    return (gaygayquan){l,r};
}
priority_queue<gaygayquan>q;
int main(){
    memset(first,-1,sizeof(first));
    n=read();int i,j,v;gaygayquan gay;
    for(i=1;i<=n;i++) a[i]=read();
    sort(a+1,a+n+1);
    for(i=1;i<=n;i++){
        for(j=1;j<i;j++){
            if(gcd(a[i],a[j])==1) g[i][j]=g[j][i]=1;
        }
    }
    for(i=1;i<=n;i++) if(!vis[i]) dfs(i);
    for(i=1;i<=n;i++) if(!in[i]) q.push(mp(a[i],i));
    while(!q.empty()){
        gay=q.top();q.pop();
        printf("%d ",gay.val);
        for(i=first[gay.id];~i;i=e[i].next){
            v=e[i].to;in[v]--;
            if(in[v]==0) q.push(mp(a[v],v));
        }
    }
}

[AGC010E] Rearranging [拓扑排序+堆]

标签:操作   char   define   href   ice   etc   push   fine   operator   

原文地址:https://www.cnblogs.com/dedicatus545/p/9475424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!