Description

给定一个\(N\)个点\(M\)条边的\(DAG(N,M\leq10^6)\),边权为\(1\)。删去一个点,使剩余图中的最长路径最短,求删去的点和最长路径长度。

Solution

神仙而有趣的一题\(Orz\),可能讲的不是很清楚\(QAQ\)

先求出终点为\(u\)的最长路\(f_u\)和起点为\(u\)的最长路\(g_u\),经过\((u,v)\)边的最长路为\(f_u+g_v+1\),这个可以用建正反图然后拓扑排序得到。

考虑删除\(u\)点,即不经过\(u\)的入边与出边的最长路,暴力就是把所有最长路权值丢到数据结构中,然后每次删除一些权值后统计答案,复杂度\(O(n^2logn)\),难以接受。

考虑\(DAG\)的性质,每一条边\((u->v)\)中\(u\)的拓扑序小于\(v\)。所以考虑按拓扑序处理,处理\(u\)前,把反图的出边相关信息\(pop\),统计答案后把正图的出边相关信息\(push\)。

然后我们需要一个支持\(pop,push\)指定数并求出\(max\)的数据结构,用两个堆(优先队列)就可以做到了。

Code

#include<cstdio>
#include<vector>
#include<queue>
#define rep(i, a, b) for (register int i=(a); i<=(b); ++i)
#define per(i, a, b) for (register int i=(a); i>=(b); --i)
using namespace std;
const int N=500005;
vector<int> G[N], IG[N];
struct Priority_queue
{
priority_queue<int> a, b;
void push(int x){a.push(x);}
void pop(int x){b.push(x);}
int top()
{
while (!b.empty() && a.top()==b.top())
a.pop(), b.pop();
return a.top();
}
}Q;
int deg[N], q[N], f[N], g[N], l, r, ans, pos; inline int read()
{
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
} int main()
{
int n=read(), m=read(); ans=m;
rep(i, 1, m)
{
int u=read(), v=read();
G[u].push_back(v); IG[v].push_back(u);
deg[v]++;
}
rep(i, 1, n) if (!deg[i]) q[++r]=i;
while (l<r)
{
int u=q[++l];
for (int v: G[u]) if (!(--deg[v])) q[++r]=v;
}
rep(i, 1, n)
{
int u=q[i];
for (int v: G[u]) f[v]=max(f[v], f[u]+1);
}
per(i, n, 1)
{
int u=q[i];
for (int v: IG[u]) g[v]=max(g[v], g[u]+1);
}
rep(i, 1, n) Q.push(g[i]), Q.push(-1);
rep(i, 1, n)
{
int u=q[i];
for (int v: IG[u]) Q.pop(f[v]+g[u]+1);
Q.pop(g[u]);
if (ans>Q.top()) ans=Q.top(), pos=u;
for (int v: G[u]) Q.push(f[u]+g[v]+1);
Q.push(f[u]);
}
printf("%d %d\n", pos, ans);
return 0;
}

POI2014 RAJ-Rally的更多相关文章

  1. [POI2014]RAJ(最短路,拓扑排序)

    对于一个点 \(x\) 如何求答案? 由于这个图是个有向无环图,可以先拓扑排序一遍,求出每个点的拓扑序,从起点到它的最长路 \(d2\),从它到终点的最长路 \(d1\).(我写代码是这么写的,注意顺 ...

  2. 【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)

    [BZOJ3832][POI2014]Rally(拓扑排序,动态规划) 题面 BZOJ,权限题 洛谷 题解 这题好强啊,感觉学了好多东西似的. 首先发现了一个图画的很好的博客,戳这里 然后我来补充一下 ...

  3. 3832: [Poi2014]Rally

    3832: [Poi2014]Rally 链接 分析: 首先可以考虑删除掉一个点后,计算最长路. 设$f[i]$表示从起点到i的最长路,$g[i]$表示从i出发到终点的最长路.那么经过一条边的最长路就 ...

  4. BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序

    题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...

  5. 【BZOJ】3832: [Poi2014]Rally

    题意 \(n(2 \le n \le 500000)\)个点\(m(1 \le m \le 1000000)\)条边的有向无环图,找到一个点,使得删掉这个点后剩余图中的最长路径最短. 分析 神题不会做 ...

  6. BZOJ 3832: [Poi2014]Rally

    Sol 线段树+拓扑序. 先把图的拓扑序搞出来,然后统计从起点到该点最长链,从该点到终点的最长链,然后建个起点终点,这里跟网络流很像,把它统一到一个有起点的图中,这里也要注意下细节处理.S,T的一个边 ...

  7. BZOJ3832 : [Poi2014]Rally

    f[0][i]为i出发的最长路,f[1][i]为到i的最长路 新建源汇S,T,S向每个点连边,每个点向T连边 将所有点划分为两个集合S与T,一开始S中只有S,其它点都在T中 用一棵线段树维护所有连接属 ...

  8. [POI2014]Rally

    OJ题号:BZOJ3832.洛谷3573 思路: 建立超级源汇$S$和$T$,DP求出分别以$S$和$T$为源点的最长路$diss$和$dist$. 对于每条边$i$,设定一个权值$w_i=diss_ ...

  9. BZOJ3832: [Poi2014]Rally(拓扑排序 堆)

    题意 题目链接 Sol 最直观的思路是求出删除每个点后的最长路,我们考虑这玩意儿怎么求 设\(f[i]\)表示以\(i\)结尾的最长路长度,\(g[i]\)表示以\(i\)开始的最长路长度 根据DAG ...

  10. BZOJ:3832: [Poi2014]Rally

    题意: 给出$DAG$,询问删掉哪个点之后最长路径最短 思路: 我们令$f[x]$表示从最远的点到达它的距离,$g[x]$表示它能够到达最远的点的距离 那么对于$(x -> y)$一条边来说,它 ...

随机推荐

  1. IIS6.0创建新网站后,浏览显示需输入用户名和密码

    1.首先我们需要创建一个用于匿名访问的账号. 我的电脑右键,电脑管理->本地用户和组->用户->新用户 注意勾选(用户不能更改密码和密码永不过期这两项)   2.右键新创建的用户-& ...

  2. mysql 执行多线程临时方案

    sqr::IDatabase *db=NULL;IDbConnection *conn = NULL;int main(int argc, char* argv[]) { db = GetDataba ...

  3. centos 安装或更新最新版本软件包(git python etc)的方法 SCL IUS

    使用centos 经常发现官方提供的软件包版本过低,很多时候大家会选择下载源码自行编译,带来了很多麻烦. centos安装最新版本软件包,例如git,python等,可以通过红帽官方提供的softwa ...

  4. 启动 nexus, major.minor 51.0 版本不支持

    a).Nexus的2.6版本及其以后版本 使用的Java的jdk7. b).Nexus的2.0-2.5版本 使用Java的jdk6的update30版本及其以后的jdk6版本 使用Java的jdk7的 ...

  5. jquery 元素筛选 13.6.20

    <ul> <li>list item 1</li> <li>list item 2</li> <li class="thir ...

  6. 去掉字符串前后的空格和Tab

    <script language=Javascript>function String.prototype.Trim() {return this.replace(/(^\s*)|(\s* ...

  7. 2018.09.15 poj2117Electricity(割点)

    传送门 其实求一个图删除一个点之后,联通块最多有多少. 直接tarjan求割点更新答案就行了. 但注意原图不一定连通. 代码: #include<iostream> #include< ...

  8. hdu-1066(大数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1066 思路:统计2的个数,如果遇到5,就抵消,最后求和加上为来得及抵消的2的个数. 参考文章:http ...

  9. Pywinauto 基于Win32 程序的自动化功能测试工具

    1.  前提条件 ü  Python2.6 下载地址:http://ishare.iask.sina.com.cn/f/8173206.html ü  Pywinauto-0.4.1 下载地址:htt ...

  10. Python 实现WC功能

    GitHub仓库:https://github.com/15crmor/PAC 项目要求 基本要求 -c 统计文件字符数 (实现) -w 统计文件词数 (实现) -l 统计文件行数(实现) 扩展功能 ...