一道思维神题....

我们像网络流一样加入原点S,与汇点T

用f[i]表示原点到i的最长路,用g[i]表示i到汇点的最长路

f数组与g数组都可以dp求出来的

接下来考虑如何通过这些信息来维护删除某个点的最长路

用拓扑序来删点

我们先将所有g数组加入一个集合中,

每次删点是就先将所有该点的入边的点的f[i]+g[x]从集合中删掉

然后此时集合中最大值就是删除这个点的最优解

然后再将每个点的出边i的f[x]+g[i]加入集合中

可以发现这个集合可以用堆来维护

# include<iostream>
# include<cstdio>
# include<cmath>
# include<cstring>
# include<algorithm>
# include<queue>
using namespace std;
const int mn = ;
struct Grap{
struct edge{int to,next;};
edge e[mn*];
int head[mn],edge_max;
void add(int x,int y)
{
e[++edge_max].to=y;
e[edge_max].next=head[x];
head[x]=edge_max;
}
}A,B;
int deg[mn*],n,m,a[mn*];
int f[mn*],g[mn*];
void topolpgy()
{
int tail=,head=;
for(int i=;i<=n;i++)
if(!deg[i]) a[++head]=i;
//printf("%d %d\n",tail,head);
while(tail<=head)
{
int u=a[tail];
tail++;
for(int i=A.head[u];i;i=A.e[i].next)
{
deg[A.e[i].to]--;
if(!deg[A.e[i].to]) a[++head]=A.e[i].to;
}
}
}
struct Heap{
int heap[mn*],mark[mn*],top;
void ins(int x)
{
if(mark[x])
{
--mark[x];
return ;
}
heap[++top]=x;
int t=top;
while(t>)
{
if(heap[t]>heap[t>>])
swap(heap[t],heap[t>>]),t>>=;
else
break;
}
}
void del(int x)
{
mark[x]++;
}
void Pop()
{
heap[]=heap[top--];
int t=;
while(t<=top)
{
if( t<top && heap[t+]>heap[t] )
t++;
if(heap[t]>heap[t>>])
swap(heap[t],heap[t>>]),t<<=;
else
break;
}
}
int Top()
{
while(mark[heap[]])
mark[heap[]]--,Pop();
return heap[];
}
}T;
int main()
{
int x,y;
A.edge_max=,B.edge_max=;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
A.add(x,y),B.add(y,x);
deg[y]++;
}
topolpgy();
/*for(int i=1;i<=n;i++)
printf("%d ",a[i]);*/
int ans=,ans_len=0x3f3f3f3f;
for(int i=;i<=n;i++)
{
int u=a[i];
f[u]=max(f[u],);
for(int j=A.head[u];j;j=A.e[j].next)
f[A.e[j].to]=max(f[A.e[j].to],f[u]+);
}
for(int i=n;i>=;i--)
{
int u=a[i];
g[u]=max(g[u],);
for(int j=A.head[u];j;j=A.e[j].next)
g[u]=max(g[u],g[A.e[j].to]+);
}
/*for(int i=1;i<=n;i++)
printf("%d:%d %d\n",i,f[i],g[i]);*/
for(int i=;i<=n;i++)
T.ins(g[i]);
T.ins();
for(int i=;i<=n;i++)
{
int u=a[i];
for(int j=B.head[u];j;j=B.e[j].next)
{
T.del(f[B.e[j].to]+g[u]);
//printf("%d ",f[B.e[j].to]+g[u]);
}
//printf("\n");
T.del(g[u]);
if(T.Top()<ans_len)
{
ans_len=T.Top(),ans=u;
//printf("%d ",T.Top());
}
for(int j=A.head[u];j;j=A.e[j].next)
{
T.ins(f[u]+g[A.e[j].to]);
//printf("%d ",f[u]+g[B.e[j].to]);
}
T.ins(f[u]);
//printf("%d\n",ans_len-1);
}
printf("%d %d",ans,ans_len-);
return ;
}

最新文章

  1. windows 共享文件夹 给 mac
  2. python基础之day1
  3. 1.0、Struts2的简单搭建方法
  4. MAC下彻底解决mysql无法插入和显示中文
  5. MFC程序执行顺序 .
  6. 强大的Spring缓存技术(中)
  7. Android 热补丁和热修复
  8. 基础知识系列☞GET和POST→及相关知识
  9. C#中messagebox用法
  10. hdu 5067 Harry And Dig Machine
  11. mysql语句在node.js中的写法
  12. [2017-07-18]logstash配置示例
  13. WPF 完美截图 &lt;二&gt;
  14. 用nodejs实现简单爬虫
  15. 红米手机4A怎么样刷入开发版获得ROOT权限
  16. Loadrunner学习资料
  17. LockSupport浅析
  18. python模块之random
  19. Spark基本架构及原理
  20. 【python38--面向对象继承】

热门文章

  1. 2.快速创建springboot项目 连pom文件里面的配置都不用配了
  2. java内部类和静态内部类
  3. nginx 下开启pathinfo模式
  4. 【python之路25】正则表达式
  5. linux系统之间互传文件
  6. web前端学习(四)JavaScript学习笔记部分(10)-- JavaScript正则表达式
  7. Python当前进程信息 (os包)
  8. node 和npm环境安装
  9. mysql与hibernate选择某个字段的最大值,比如表中的最大id
  10. maven下载安装以及环境配置