【EOJ Monthly 2019.02 - E】中位数(二分 ,中位数 ,−1/1变换,dp求解DAG最长路)

题干:

E. 中位数

单测试点时限: 10.0 秒

内存限制: 256 MB

“你的地图是一张白纸,所以即使想决定目的地,也不知道路在哪里。”

QQ 小方最近在自学图论。他突然想出了一个有趣的问题:

一张由 n 个点,m 条边构成的有向无环图。每个点有点权 Ai 。QQ 小方想知道所有起点为 1 ,终点为 n 的路径中最大的中位数是多少。

一条路径的中位数指的是:一条路径有 n 个点,将这 n 个点的权值从小到大排序后,排在位置 ⌊n2⌋+1 上的权值。

输入

第 1 行输入两个正整数 n,m (1≤n≤106,1≤m≤106 ),表示结点数量和边的数量。

第 2 行输入 n 个由空格隔开的整数 Ai (0≤Ai≤109 ),表示点权。

接下来 m 行,每行输入两个整数 x,y (1≤x,y≤n ),表示有一条 x 指向 y 的单向边,保证给出的图是联通的,可能存在重边。

输出

输出一行包含一个整数,表示最大的中位数。如果不存在任何一条起点为 1 ,终点为 n 的路径,则输出 −1 。

样例

Input

5 5
1 2 3 4 5
1 2
2 3
3 5
2 4
4 5

Output

4

解题报告:

考虑二分答案,我们需要验证路径最大的中位数是否 ≥mid 。

我们把所有的点权做 −1/1 变换,即 ≥mid 的点权变为 1 ,否则变为 −1 。

根据题面路径中位数的定义,我们可以发现,如果这条路径的中位数 ≥mid ,那么做了 −1/1 变换以后这条路径上的点权和 ≥0 。

而我们现在需要知道的问题是路径最大的中位数是否 ≥mid ,也就是说,最大的路径点权是否 ≥0 。

跑一遍最长路就好了。而对于 DAG ,最长路只要 dp 一下,复杂度是保证 O(m) 。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e6 + 5;
ll val[MAX],b[MAX],a[MAX];
int head[MAX];
ll dis[MAX];
int tot,flag;
bool vis[MAX];
int n,m;
struct Node {int to;int ne;
} e[MAX];
void add(int u,int v) {e[++tot].ne = head[u];e[tot].to = v;head[u] = tot;
}
void dfs(int cur,int rt) {if(vis[cur]) return ;vis[cur] = 1;if(cur == n) {flag = 1;dis[n] = val[n];return ;}dis[cur] = -0x3f3f3f3f;for(int i = head[cur]; i!=-1; i=e[i].ne) {int v = e[i].to;if(v == rt) continue;dfs(v,cur);dis[cur] = max(dis[cur],dis[v]);}dis[cur] += val[cur];
}
bool ok(ll x) {for(int i = 1; i<=n; i++) {if(a[i] >= x) val[i] = 1;else val[i] = -1;}memset(vis,0,sizeof vis);dfs(1,-1);return dis[1] >= 0;
}
int main()
{cin>>n>>m;memset(head,-1,sizeof head);for(int i = 1; i<=n; i++) scanf("%lld",val + i),a[i] = b[i] = val[i];//注意本题中点权为正 for(int u,v,i = 1; i<=m; i++) {scanf("%d%d",&u,&v);add(u,v);}memset(vis,0,sizeof vis);dfs(1,-1);if(flag == 0) {puts("-1");return 0 ;}sort(b+1,b+n+1);int x = unique(b+1,b+n+1) - b - 1;ll l = 1,r = x,mid,ans;while(l<=r) {mid = (l+r)>>1;if(ok(b[mid])) {ans = mid;l = mid+1;}else r = mid-1;}printf("%lld\n",b[ans]);return 0 ;}

为啥这样就超时。。:(有没有大佬来解释一下这样记忆化为啥不对啊,,欢迎留言区讨论)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e6 + 5;
ll val[MAX],b[MAX],a[MAX];
int head[MAX];
ll dis[MAX];
int tot,flag;
int n,m;
struct Node {int to;int ne;
} e[MAX];
void add(int u,int v) {e[++tot].ne = head[u];e[tot].to = v;head[u] = tot;
}
ll dfs(int cur,int rt) {if(dis[cur] != -0x3f3f3f3f) return dis[cur];if(cur == n) {flag = 1;dis[n] = val[n];return dis[n];}for(int i = head[cur]; i!=-1; i=e[i].ne) {int v = e[i].to;if(v == rt) continue;ll tmp = dfs(v,cur);dis[cur] = max(dis[cur],tmp);}dis[cur] += val[cur];return dis[cur];
}
bool ok(ll x) {for(int i = 1; i<=n; i++) {if(a[i] >= x) val[i] = 1;else val[i] = -1;}for(int i = 1; i<=n; i++) dis[i] = -0x3f3f3f3f;dfs(1,-1);return dis[1] >= 0;
}
int main()
{cin>>n>>m;memset(head,-1,sizeof head);for(int i = 1; i<=n; i++) scanf("%lld",val + i),a[i] = b[i] = val[i];//注意本题中点权为正 for(int u,v,i = 1; i<=m; i++) {scanf("%d%d",&u,&v);add(u,v);}for(int i = 1; i<=n; i++) dis[i] = -0x3f3f3f3f;dfs(1,-1);if(flag == 0) {puts("-1");return 0 ;}sort(b+1,b+n+1);int x = unique(b+1,b+n+1) - b - 1;ll l = 1,r = x,mid,ans;while(l<=r) {mid = (l+r)>>1;if(ok(b[mid])) {ans = mid;l = mid+1;}else r = mid-1;}printf("%lld\n",b[ans]);return 0 ;}

补充:如果要求:排在位置上的数。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e6 + 5;
ll val[MAX],b[MAX],a[MAX];
int head[MAX];
ll dis[MAX];
int tot,flag;
bool vis[MAX];
int n,m;
struct Node {int to;int ne;
} e[MAX];
void add(int u,int v) {e[++tot].ne = head[u];e[tot].to = v;head[u] = tot;
}
void dfs(int cur,int rt) {if(vis[cur]) return ;vis[cur] = 1;if(cur == n) {flag = 1;dis[n] = val[n];return ;}dis[cur] = -0x3f3f3f3f;for(int i = head[cur]; i!=-1; i=e[i].ne) {int v = e[i].to;if(v == rt) continue;dfs(v,cur);dis[cur] = max(dis[cur],dis[v]);}dis[cur] += val[cur];
}
bool ok(ll x) {for(int i = 1; i<=n; i++) {if(a[i] > x) val[i] = 1;else val[i] = -1;}memset(vis,0,sizeof vis);dfs(1,-1);return dis[1] <= 0;
}
int main()
{cin>>n>>m;memset(head,-1,sizeof head);for(int i = 1; i<=n; i++) scanf("%lld",val + i),a[i] = b[i] = val[i];//注意本题中点权为正 for(int u,v,i = 1; i<=m; i++) {scanf("%d%d",&u,&v);add(u,v);}memset(vis,0,sizeof vis);dfs(1,-1);if(flag == 0) {puts("-1");return 0 ;}sort(b+1,b+n+1);int x = unique(b+1,b+n+1) - b - 1;ll l = 1,r = x,mid,ans;while(l<=r) {mid = (l+r)>>1;if(ok(b[mid])) {ans = mid;r = mid-1;}else l = mid+1;}printf("%lld\n",b[ans]);return 0 ;}/*
4 3
1 2 3 4
1 2
2 3
3 4*/

另一种求DAG最长路的方法: 

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX=1000006;
int n,m,v[MAX],d[MAX],g[MAX],p[MAX],t[MAX],vis[MAX];
vector<int>G[MAX];
inline int check(int x) {for(int i=1; i<=n; ++i)p[i]=v[i]>=x?1:-1,t[i]=-1e9,g[i]=d[i];t[1]=p[1];queue<int>q;q.push(1);for(int u; !q.empty(); q.pop())for(auto v:G[u=q.front()]) {if(t[v]<t[u]+p[v]) t[v]=t[u]+p[v];if(!--g[v]) q.push(v);}return t[n]>=0;
}
int main() {cin>>n>>m;for(int i=1; i<=n; ++i)scanf("%d",v+i);if(n==1)return 0*printf("%d\n",v[1]);for(int i=1,x,y; i<=m; ++i) {scanf("%d%d",&x,&y);G[x].push_back(y),++d[y];}queue<int>q;q.push(1),vis[1]=1;for(int u; !q.empty(); q.pop())for(auto v:G[u=q.front()])if(!vis[v]) vis[v]=1,q.push(v);for(int i=1; i<=n; ++i)if(!vis[i])for(auto v:G[i]) d[v]--;int l=0,r=1e9,mid,ans=-1;while(l<=r) {mid=(l+r)>>1;if(check(mid))ans=mid,l=mid+1;elser=mid-1;}printf("%d\n",ans);
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【EOJ Monthly 2019.01 - E】唐纳德先生与假骰子(假概率问题)

题干&#xff1a; 单测试点时限: 6.0 秒 内存限制: 1024 MB 嗨&#xff0c;唐纳德先生又来了。 他又带了一枚假骰子&#xff0c;这个骰子的各个面的点数依然是 1,2,3,4,5,6 &#xff0c;但是六个面向上的概率却不一定都是 1/6 &#xff0c;而变成了 p1,p2,p3,p4,p5,p6 。 …

linux搜索pdf文件,桌面应用|如何使用 pdfgrep 从终端搜索 PDF 文件

诸如 grep 和 ack-grep 之类的命令行工具对于搜索匹配指定正则表达式的纯文本非常有用。但是你有没有试过使用这些工具在 PDF 中搜索&#xff1f;不要这么做&#xff01;由于这些工具无法读取PDF文件&#xff0c;因此你不会得到任何结果。它们只能读取纯文本文件。顾名思义&…

【CodeForces - 546C 】Soldier and Cards (模拟)

题干&#xff1a; Two bored soldiers are playing card war. Their card deck consists of exactly n cards, numbered from 1 to n, all values are different. They divide cards between them in some manner, its possible that they have different number of cards. Th…

c 语言 while break,26 C 语言中的break和continue - C 语言基础教程

循环语句很好用&#xff0c;但是如果循环进行到一般想要跳出循环或者结束循环怎么办&#xff1f;那么那你需要 break 和 continue 语句。1. break 和 continue 的使用语法1.1 or 循环中使用 break 和 continuebreakfor (控制循环的变量; 循环判断条件; 循环变量增减变化){语句1…

android开发百度地图坐标偏差,利用百度地图Android sdk高仿微信发送位置功能及遇到的问题...

接触了百度地图开发平台半个月了&#xff0c;这2天试着模仿了微信给好友发送位置功能&#xff0c;对百度地图的操作能力又上了一个台阶我在实现这个功能的时候&#xff0c;遇到一些困难&#xff0c;可能也是别人将会遇到的困难&#xff0c;特在此列出1、在微信发送功能中&#…

kali linux 截图 软件,Kali-Linux-Tools-Interface:针对Kali Linux的图形化Web接口

Kali-Linux-Tools-Interface在当今这个信息时代&#xff0c;数据是最有价值的资产&#xff0c;因此&#xff0c;广大用户和企业已成为网络攻击的主要目标。众所周知&#xff0c;信息安全专业人员都会使用一系列技术工具来协助他们的活动。但是设置环境&#xff0c;安装这些工具…

android布局属性,Android 布局学习之——LinearLayout属性baselineAligned的作用及baseline...

相信大家对LinearLayout已经相当熟悉&#xff0c;但你们是否了解它的属性baselineAligned呢&#xff1f;Android官方文档是这么描述的&#xff1a;那到底这个属性是做什么用的呢&#xff1f;baselineAligned:基准线对齐。首先要解释什么是基准线&#xff0c;这个在中文中不常见…

android取消自动调试模式吗,Android进入调试模式的三种技巧

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;Android开发过程中难免会遇到各种问题&#xff0c;通常我们会通过打印Log日志或者Debug模式来分析问题。这里介绍下Android程序进入到Debug的多种方式&#xff0c;…

IMX6怎么移植最新Android,[IMX6Q][Android5.1]移植筆記 --- 無法掛載system文件系統

platform: imx6qos: Android5.1branch: l5.1.1_2.1.0-ga編譯好system image之后開機提示如下log&#xff0c;注意紅色部分:Freeing unused kernel memory: 432K (c0be3000 - c0c4f000)usb 1-1: USB disconnect, device number 2Console: switching to colour dummy device 80x3…

【POJ - 1456】Supermarket (贪心,优先队列 或并查集)

题干&#xff1a; A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an integral number of time units starting from the moment the sale begins. Each product takes precis…

【CodeForces - 558C】Amr and Chemistry(位运算,bfs,计数,思维,tricks)

题干&#xff1a; Amr loves Chemistry, and specially doing experiments. He is preparing for a new interesting experiment. Amr has n different types of chemicals. Each chemical i has an initial volume of ailiters. For this experiment, Amr has to mix all th…

我家云刷android系统教程,我家云刷机教程——小白详细版(篇二)

#大男孩的快乐#征稿活动火热进行中。只要投稿就有50金币等你拿&#xff0c;更有三千元乐高大奖与达人Z计划专属权益等待优秀的你~>活动详情戳这里<前两天发了一篇我家云的刷机教程&#xff0c;没想到大家这么有兴趣&#xff0c;讨论的异常激烈。看了大家的评论才发现之前…

【Loj - 515】贪心只能过样例(暴力,或01背包 + bitset)

题干&#xff1a; 题目描述 输入格式 第一行一个数 n。 然后 n 行&#xff0c;每行两个数表示 ai​,bi​。 输出格式 输出一行一个数表示答案。 样例 样例输入 5 1 2 2 3 3 4 4 5 5 6 样例输出 26 数据范围与提示 解题报告&#xff1a; 注意到要求统计种类数&#xf…

html loader的作用,webpack认识loader的作用

举例&#xff1a;如果希望在.html文件中使用style.css样式&#xff0c;我们以前只学习过一种方式&#xff1a;直接在.html中通过link的方式来引入 &#xff0c;这是传统的做法&#xff0c;在webpack语境下&#xff0c;我们将选择一条不同的道路&#xff1a;在js文件中引入了css…

5可视化数据大屏模板_可视化大屏模板分享

3个月前的一天&#xff0c;老板找到我&#xff1a;“小王&#xff0c;数据怎么才能产生让人惊艳的感觉呢&#xff1f;”我说&#xff1a;“肯定是用代码让程序员操作一下&#xff0c;再让设计师做一下配色&#xff0c;最好还能是数据实时变化的那种&#xff0c;简直就和电影里一…

c#12星座速配代码_白羊座今日运势|2020/12/11

整体运势&#xff1a;★★★☆☆爱情运势&#xff1a;★★☆☆☆事业运势&#xff1a;★★☆☆☆财富运势&#xff1a;★★★☆☆幸运数字&#xff1a;7速配星座&#xff1a;金牛座幸运颜色&#xff1a;橙色幸运时刻&#xff1a;12:00-14:00整体运势&#xff1a;接收的消息会比…

怎么去掉拼写检查的红线_发动机温度过高,水箱“开锅”,我们到底该怎么办?...

车子开久了&#xff0c;难免会出现一些小故障&#xff0c;今天我们就来说一下关于发动机水温过高的问题&#xff0c;这也是老司机常说的“开锅”。发动机水温正常情况是在80-90摄氏度之间&#xff0c;一旦超过这个温度&#xff0c;也就是水温表过了红线的时候&#xff0c;我们就…

【ZOJ - 2972】Hurdles of 110m (dp)

题干&#xff1a; In the year 2008, the 29th Olympic Games will be held in Beijing. This will signify the prosperity of China and Beijing Olympics is to be a festival for people all over the world as well. Liu Xiang is one of the famous Olympic athletes i…

格式说明_ISO11784/85 FDX-B动物芯片格式写码说明

植入式生物芯片口蹄疫、疯牛病、禽流感、非洲猪瘟的蔓延严重危及人类生命安全&#xff0c;引发了人们对动物性食品生产全过程安全追溯管理的重视。因此&#xff0c;有效地利用非接触式无线射频技术(RFID)对其进行控制成为有效的重要手段。一、国际动物识别标准介绍ISO 11784&am…

1至9填入九个方框内_防水涂料和施工堵漏的“五大技巧”和“九个细节”

防水涂料和施工堵漏的“五大技巧”和“九个细节”很多业主会在留言里问我家里水管堵了、房顶渗水怎么办&#xff0c;所以防水问题不可忽视。让您住的安心&#xff0c;您楼下的邻居也住的安心。对于防水问题&#xff0c;一定要在最初进行装修的时候就特别注意。下面这些是专业人…