【jzoj4878】【时空传送】【最短路】

来源:互联网 发布:matlab高维数据可视化 编辑:程序博客网 时间:2024/05/01 05:09

题目大意

给出一个有向无环图,求删除一个点是最长路最小,求删除那个点和删除后的最长路。

解题思路

先求出一个点往前往后的最长路,按拓扑序枚举点用数据结构维护最长路,先删除往后的最长路和经过入边的最长路,统计答案,然后加入到前面的最长路和经过出边的最长路。能这样做是因为是一个有向无环图按拓扑序做,删除当前点后面的路显然没有贡献,不经过当前点的路一定已经加入,过了这个点显然不会再影响,所以可以放心加入,只要处理一下直接相连的变就可以了。

code

#include<set>#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define LL long long#define LD double#define max(a,b) ((a>b)?a:b)#define min(a,b) ((a>b)?b:a)#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const inf=1e9;int const maxn=7.5*1e4,maxm=1e5;int n,m,gra[2],to[2][maxm+10],next[2][maxm+10],begin[2][maxn+10],q[maxn+10],dis[2][maxn+10],pre[maxn+10];void insert(int u,int v,int w){    to[w][++gra[w]]=v;    next[w][gra[w]]=begin[w][u];    begin[w][u]=gra[w];}multiset<int> s;int main(){    //freopen("chronosphere.in","r",stdin);    //freopen("chronosphere.out","w",stdout);    freopen("d.in","r",stdin);    freopen("d.out","w",stdout);    scanf("%d%d",&n,&m);    fo(i,1,m){        int x,y;scanf("%d%d",&x,&y);pre[y]++;        insert(x,y,0);insert(y,x,1);    }    int tail=0;    fo(i,1,n)if(!pre[i])q[++tail]=i;    for(int i=1;i<=tail;i++)        for(int j=begin[0][q[i]];j;j=next[0][j]){            dis[0][to[0][j]]=max(dis[0][to[0][j]],dis[0][q[i]]+1);            if(!(--pre[to[0][j]]))q[++tail]=to[0][j];        }    fd(i,n,1)        for(int j=begin[0][q[i]];j;j=next[0][j])            dis[1][q[i]]=max(dis[1][q[i]],dis[1][to[0][j]]+1);    int ans=inf,ans2;    fo(i,1,n)s.insert(dis[1][q[i]]);    fo(i,1,n){        s.erase(s.find(dis[1][q[i]]));        for(int j=begin[1][q[i]];j;j=next[1][j])            s.erase(s.find(dis[0][to[1][j]]+dis[1][q[i]]+1));        int tmp=*--s.end();        if((tmp<ans)||((tmp==ans)&&(ans2>q[i]))){            ans=tmp;            ans2=q[i];        }        for(int j=begin[0][q[i]];j;j=next[0][j])            s.insert(dis[0][q[i]]+dis[1][to[0][j]]+1);        s.insert(dis[0][q[i]]);    }    printf("%d %d",ans2,ans);}
0 0