首页 > 其他分享 >字典序相关贪心

字典序相关贪心

时间:2023-04-18 23:44:20浏览次数:31  
标签:连通 int dfs define 2020 相关 贪心 col 字典

AGC010E

【题意】
给定一张 \(n\) 个节点的无向图,点有点权,小 A 要给每条边定向,使得无向图依然是DAG,然后小 B 取出一个拓扑序。小 A 的目标是最大化拓扑序,小 B 的目标是让拓扑序的点权字典序最小。
\(n \le 2000, m \le n(n-1)/2\)

【分析】
这题你要是直接从拓扑序来考虑,想到某一个位置放 \(i\) 行不行,会发现你为了让比它更大的不能和它抢,会需要打标记,这个标记十分具有后效性,不太好维护。

乍一看没啥思路了现在,但是你可以随便推下性质!首先对于每个连通块,它们可以独立考虑,其关系是归并关系。

你考虑连通块有什么好的性质!你会发现,对于 \(m = n - 1\) 的情况,可以定向为一棵树,而 \(m \ge n\) 的情况,可以当作一个外向基环树加上若干条边,然后对于外向基环树改一条边的方向,其他边随便定向下,就可以让某一个点是唯一一个没有入边的点。

image

(如果红色的边很多很杂的话不一定能够在基环树的基础上构造 DAG,但是这确实是一个思路的出发点,而且实际上你从一个点开始 dfs,按照 dfn 定序即可。

总之,我们对于一个连通块是可以做到只留一个点没有入度的,而且是任意点都可以

然后考虑一定选这个点,将其所有边取外向(删掉)。接下来怎么办。分裂成了若干个连通块,但是你现在想想后效性是什么。其实就是只能选择和这个点相邻的点。然后完美递归到了子问题。

然后这个实现有很大说法。其实相当于一个 pq,往里塞所有连通块的最小点,每次取最大的点,删掉,然后将其所有相邻连通块放进去。这个过程相当于一个 bfs,但是要维护连通块信息。

但是这样做时间复杂度是 \(O(n^3)\) 的,不能通过。考虑优化,主要问题是边数很大,但是你分析一下单个连通块的发现只是一个 dfs,那么如果把这个 dfs 树建出来那么在这些森林里跑 bfs 得到的东西一样,但是复杂度 \(O(n^2)\)。

#include<bits/stdc++.h>
using namespace std;
#define int long long
//use ll instead of int.
#define f(i, a, b) for(int i = (a); i <= (b); i++)
#define cl(i, n) i.clear(),i.resize(n);
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 1e9;
//#define cerr if(false)cerr
//#define freopen if(false)freopen
#define watch(x) cerr  << (#x) << ' '<<'i'<<'s'<<' ' << x << endl
void pofe(int number, int bitnum) {
    string s; f(i, 0, bitnum) {s += char(number & 1) + '0'; number >>= 1; } 
    reverse(s.begin(), s.end()); cerr << s << endl; 
    return;
}
template <typename TYP> void cmax(TYP &x, TYP y) {if(x < y) x = y;}
template <typename TYP> void cmin(TYP &x, TYP y) {if(x > y) x = y;}
//调不出来给我对拍!
//use std::array.
int g[2020][2020];time_t alltime = 0;
int n; int a[2020];vector<int>ans;
priority_queue<int,vector<int>,less<int>> q; int col[2020]; bool vis[2020];
int cnt=0;int fa[2020];
vector<int> t[2020];
void dfs(int x, int c) {
    // cnt++;
    col[x] = c;
    f(i,1,n) if(g[x][i] && !col[i]) {
        t[x].push_back(i); fa[i]=x;
        col[i] = c; dfs(i, c);
    }
}
void bfs() {
    f(i,1,n)if(fa[i]==0){q.push(i);}
    while(!q.empty()) {
        int now = q.top(); q.pop(); ans.push_back(now);
        for(int i : t[now]) q.push(i);
    }
}
bool cmp(int x,int y){return a[x]<a[y];}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen();
    //freopen();
    //time_t start = clock();
    //think twice,code once.
    //think once,debug forever.
    cin >> n;
    f(i,1,n)cin>>a[i];
    sort(a+1,a+n+1);
    f(i,1,n)f(j,1,n){
        if(__gcd(a[i],a[j]) != 1) {
            g[i][j]=g[j][i]=1;
        }
    }
    f(i,1,n){
        if(!col[i]) dfs(i, i); 
    }
    bfs();
    for(int i:ans)cout<<a[i]<<" ";
    cout<<endl;
    //time_t finish = clock();
   // cout << "time used:" << alltime * 1.0 / CLOCKS_PER_SEC <<"s"<< endl;
    return 0;
}
/*
2023/4/18
start thinking at 16:25


start coding at h:mm
finish debugging at 22:54
*/

标签:连通,int,dfs,define,2020,相关,贪心,col,字典
From: https://www.cnblogs.com/Zeardoe/p/17331722.html

相关文章

  • echarts相关问题
    解决echarts下钻地图,在平移和缩放后,下钻到下一级时生成的地图不在容器中间,会跑到容器外面去。 myChart.setOption(option,true)问题:echart地图三级下钻地图在平移和缩放后,点击到省,由于中心点的偏移,省跑到容器以外的地方去了,导致新生成的地图看不见。解决方法:后来发现,是重新绘制......
  • 一道贪心小题
    题目在二维平面中有\(n\)只老鼠,有\(A,B\)两个洞,洞\(A\)的容量是\(k\),洞\(B\)的容量是\(n-k\)。汤姆来了,每只老鼠都要钻进洞里,给出洞\(A,B\)和每只老鼠的坐标,安排老鼠进洞使老鼠进洞总路程最短。\(1\leqn,k\leq1e5,1\leq坐标值\leq1e9\)允许误差\(1e-5\)分析因为......
  • js 选择器操作相关
    Javascript知识【jQuery选择器】 https://blog.csdn.net/m0_64550837/article/details/126231445 CSS选择器https://blog.csdn.net/weixin_44214326/article/details/128093869 ......
  • pg 物化视图相关
    一、物化视图简介类似oracle,pg的物化视图也是物理是实际存在的表。在执行某些查询时效率较低,而且使用传统方法(例如索引)无法显著提高效率,这时常用的方法是将需要查询的数据事先查好并储存起来,这样就不需要每次查询都从头执行一次。这种“缓存”机制其实就是物化视图。CREATEMA......
  • python+playwright 学习-53 模拟键盘操作-复制粘贴相关
    前言playwright可以模拟键盘操作,定位到元素使用press()方法press()方法介绍locator.press()方法聚焦所选元素并产生单个击键。它接受在键盘事件的keyboardEvent.key属性中发出的逻辑键名称:Backquote,Minus,Equal,Backslash,Backspace,Tab,Delete,Escape,ArrowDown,......
  • 3. python 列表、元组和字典
    一、序列简介序列是一种包含多项数据的数据结构python常见序列类型包括字符串、元组、列表等其中字符串与元组是不可变的,而列表是可变的元组创建列表使用(),而列表使用[]>>>my_tuple=('fff',20,'dddd')>>>print(type(my_tuple))<class'tuple'>>>>print(my_tuple)('fff�......
  • valhalla瓦片标准和相关代码
    Hierarchies/LevelsTilesaresplitupintothreelevelsorhierarchies.Hierarchy0containsedgespertainingtoroadsthatareconsideredhighway(motorway,trunk,andprimary)roadsandarestoredin4degreetiles.Hierarchy1containsroadsthatarea......
  • GCC相关
    GCC,theGNUCompilerCollection  https://gcc.gnu.org/ GCC:Anonymousread-onlyGitaccess  https://gcc.gnu.org/git.html browseourGithistoryonline https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git......
  • 大数据开发相关技术汇总
    HadoopKaflka分布式数据日志收集,生产者消费者模式。SqoopHadoop数据导入,导出工具。自动生成mapreduce。导入数据:MySQL,Oracle导入数据到Hadoop的HDFS、HIVE、HBASE等数据存储系统;导出数据:从Hadoop的文件系统中导出数据到关系数据库;特点:可以将关系型数据库中的数据导入......
  • 贪心_20230417
    452.用最少数量的箭引爆气球题目说明有一些球形气球贴在一堵用XY平面表示的墙面上。墙面上的气球记录在整数数组points,其中points[i]=[xstart,xend]表示水平直径在xstart和xend之间的气球。你不知道气球的确切y坐标。一支弓箭可以沿着x轴从不同点完全垂直地......