传送门->

这题的原理看上去很神奇。

称拓扑图中入度为0的点为“起点”,出度为0的点为“终点”。

因为“起点”和“终点”可能有很多个,算起来会很麻烦,所以新建“超级起点”S,向所有点连边,“超级终点”T,所有点向它连边。这样原图中的最长路就是新图中的最长路-2。

dis[a->b]表示a到b的距离。

对于一个拓扑图而言,它的一个割集中肯定有一条边在最长路上。对于每条边,可以将dis[S->该边起点]和dis[该边终点->T]算出,那么该边所在路径中的最长的一个就是dis[S->该边起点]+dis[该边终点->T]+1。将该边边权设为它。这样一来,最长路就是该图随便一个割集的边权最大值。

删掉一个点,就可以看成删掉这个点的所有出边。但是这样就有些问题了:所有能走到这条边的边和这条边能走到的所有边都会因为这条边删掉而受影响,要是把所有的影响都算出来,想必是不行的。这时就有一个看似可行的方法了:在删掉这个点的所有出边的图中求一个只包含与这些边不互达的边的割集,取这个割集中的边权最大值。会发现那个割集就是原图中由这个点的所有出边和一些与它不互达的边组成的一个割集。

会不会出现不互达的边不够用的情况?先把拓扑图按最长路分好层(浅蓝色的线)。

这样的话,就不会存在右->左的边。

也就是说,图中所有红边和所有蓝边都是不互达的。而删掉所有红边和所有蓝边后,就不能从左边走到右边了。这样就形成了一个割集。答案就是所有蓝边的边权最大值。

如果这个删掉的点后图变成两部分怎么办?想必是不可能的,因为对于每一个点,都有 S->该点 和 该点->T 的边,所以只要不删S、T就不会将图分成几部分。肯定会有上图中蓝边那样的边存在的。

那么问题就变成了对于每个点,求出所有与它不互达的边权的最大值,再对于所有点取最小值就行了!

好吧,这并没有把问题简化多少,至少变得相对可做了。

那么可以考虑递推。按照拓扑序枚举要删掉的点,每次将当前点变成下一个时,新的那个点的所有入边要删去,上一个点的所有出边要加入。

这是为什么呢?因为上一个状态是删掉上一个点的图,计入答案的是割集中不包括与上一个点可达的边的边权。加入上一个点的所有出边后,就刚好凑成了一个割集。此时计入答案的是原图的一个割集。但是我们要求的是删除新的点的割集,所以就要删除所有连向新的点的边。这时不会有其它与能走到该点的边。这是因为能走到该点的边的起点、终点的拓扑序都小于该点(终点是该点的边刚刚已经被删去了,不考虑)。也就是说,所有这些边的终点之前已经被考虑过了,它们的入边已经全部被删除了。而该点能到达的边的起点的拓扑序在该点之后,还没有被加入,所有不用考虑。

每次删除新的点的所有出边,会多删除吗?想必是不会的。新的点的所有入边的起点在拓扑序中都比该点靠前,所以所有入边之前都被加入了。

用什么数据结构维护呢?看上去需要支持取最大值、插入、删除,堆似乎不错。

刚刚证明了这种方法是可行的,但至于具体是怎么想出来的,我能说是去看某个大佬的博客吗?

#include<algorithm>
#include<cassert>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define re register
#define maxn 500010
#define maxm 2000010
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(isdigit(ch)==0 && ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(int x)
{
int f=0;char ch[20];
if(!x){putchar('0'),putchar(' ');return;}
if(x<0){putchar('-');x=-x;}
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar(' ');
}
int fir[2][maxn],nxt[2][maxm],v[2][maxm],id[2][maxm],cnt[2];//0:roads; 1:back roads;
int S,T,n,m,mx,mxnd;
int q[maxn],hd,tl,dis[2][maxn],in[maxn];
void ade(int u1,int v1,int id1,int f){v[f][cnt[f]]=v1,id[f][cnt[f]]=id1,nxt[f][cnt[f]]=fir[f][u1],fir[f][u1]=cnt[f]++;}
priority_queue<int>yes,no;
void inq(int x){yes.push(x);while(!no.empty()&&yes.top()==no.top())yes.pop(),no.pop();}
void deq(int x){no.push(x);while(!no.empty()&&yes.top()==no.top())yes.pop(),no.pop();}
int top(){while(!no.empty()&&yes.top()==no.top())yes.pop(),no.pop();return yes.top();}
int tmp[maxn],cntt;/*
void print()
{
cout<<"heap:"<<endl;
while(!no.empty()&&yes.top()==no.top())yes.pop(),no.pop();
while(!yes.empty())cout<<yes.top()<<" ",tmp[++cntt]=yes.top(),yes.pop();
while(cntt)yes.push(tmp[cntt--]);cout<<endl;
}*/
int main()
{
memset(fir,-1,sizeof(fir));
n=read(),m=read();
rep(i,1,m){int x=read(),y=read();ade(x,y,i,0),ade(y,x,i,1);in[y]++;}S=0,T=n+1;
rep(i,1,n)ade(S,i,i+m,0),ade(i,S,i+m,1),ade(i,T,i+m,0),ade(T,i,i+m,1),in[i]++,in[T]++;
q[++tl]=S;
while(hd<tl)
{
int u=q[++hd];
for(int k=fir[0][u];k!=-1;k=nxt[0][k])
{
int vv=v[0][k];in[vv]--;
if(in[vv]==0){q[++tl]=vv;}
}
}
rep(i,1,tl)
{
int u=q[i];
for(int k=fir[0][u];k!=-1;k=nxt[0][k])
{
int vv=v[0][k];
dis[0][vv]=max(dis[0][u]+1,dis[0][vv]);
}
}
dwn(i,tl,1)
{
int u=q[i];
for(int k=fir[0][u];k!=-1;k=nxt[0][k])
{
int vv=v[0][k];
dis[1][u]=max(dis[1][vv]+1,dis[1][u]);
}
}
mx=2147483647;
rep(i,2,tl-1)
{
int u=q[i],pu=q[i-1];
for(int k=fir[0][pu];k!=-1;k=nxt[0][k])
{
int vv=v[0][k];
inq(dis[0][pu]+dis[1][vv]+1);
}
for(int k=fir[1][u];k!=-1;k=nxt[1][k])
{
int vv=v[1][k];
deq(dis[0][vv]+dis[1][u]+1);
}
if(mx>top())mx=top(),mxnd=u;
}
write(mxnd),write(mx-2);
return 0;
}
/*
6 5
1 3
1 4
3 6
3 4
4 5
*/

  

并不对劲的bzoj3832: [Poi2014]Rally的更多相关文章

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

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

  2. BZOJ3832 [Poi2014]Rally 【拓扑序 + 堆】

    题目链接 BZOJ3832 题解 神思路orz,根本不会做 设\(f[i]\)为到\(i\)的最长路,\(g[i]\)为\(i\)出发的最长路,二者可以拓扑序后\(dp\)求得 那么一条边\((u,v ...

  3. BZOJ3832 : [Poi2014]Rally

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

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

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

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

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

  6. 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)

    3832: [Poi2014]Rally Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 168  Solved:  ...

  7. 3832: [Poi2014]Rally

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

  8. [POI2014]Rally

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

  9. 【bzoj3832】Rally

    Portal -->bzoj3832 Description ​ 给你一个DAG,每条边长度都是\(1\),请找一个点满足删掉这个点之后剩余图中的最长路最短 Solution ​​ 这题的话感觉 ...

随机推荐

  1. noip 2010 数字统计

    数位dp解水题 luogu1179 dp[i][j]表示 有i位,且首位是j(包括0) 的 ‘2’的个数 dp[i][j]={ Σ(dp[i-1][k]),j!=2; Σ(dp[i-1][k])+va ...

  2. hdu4514(非连通图的环判断与图中最长链)(树的直径)

    湫湫系列故事——设计风景线 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好.  ...

  3. jvm参数设置 -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M

    -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M 这里有几个问题: 1. 各个参数的含义什么? 2. 为什么有的机器我将- ...

  4. Hybris Virtualjdbc Extension

    作者:Eason 编写日期:2018/07/31 联系方式:13920409462 1. Extension 说明 virtualjdbc extension 提供了虚拟JDBC驱动程序的实现. 通过 ...

  5. HDU 6390

    GuGuFishtion Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  6. HDU 5521 Meeting【最短路】

    今天旁观了Angry_Newbie的模拟区域赛(2015shenyang) 倒着看最先看的M题,很明显的最短路问题,在我看懂的时候他们已经开始敲B了. 后来听说D过了很多人.. D题一看是个博弈,给了 ...

  7. Codeforces 954 D Fight Against Traffic

    Discription Little town Nsk consists of n junctions connected by m bidirectional roads. Each road co ...

  8. "格式太旧或是类型库无效。 (异常来自 HRESULT:0x80028019 (TYPE_E_UNSUPFORMAT))"

    错误提示内容: “System.Runtime.InteropServices.COMException (0x80028019): 格式太旧或是类型库无效. (异常来自 HRESULT:0x8002 ...

  9. 我的Android Studio 优化之路

    改动keymap 改动经常使用的快捷键 代码补全(Eclipse: ALT+/) Android Studio中默认用的是Ctrl+Space, 这跟输入法切换冲突.找到Keymap->Main ...

  10. C++设计模式之适配器模式(二)

    3.Socket网络通信的设计与实现------类适配器 除了对象适配器模式之外.适配器模式另一种形式.那就是类适配器模式,类适配器模式和对象适配器模式最大的差别在于适配器和适配者之间的关系不同,对象 ...