BZOJ 2725 [Violet 6]故乡的梦

来源:互联网 发布:淘宝网牛仔裤女款 编辑:程序博客网 时间:2024/05/01 02:29

堆优dijkstra+线段树

膜:http://blog.csdn.net/popoqqq/article/details/47841783

为了表达清楚,记不删边时最短路为E1,删去某一条E1上的边之后的最短路为E2

显然E2一定是形如:S->沿着E1走到某一个在E1上点的S’->沿着不属于E1的一些边走到某一在E1上点的T’->沿着E1走到T

而且可以证明,上面提到的E2中不属于E1的那些边(组成一条路径)中,一定存在至少一条边,记它的两端点为u,v,使得E2上沿着S->u的路径是S->u在原图中的最短路,E2上沿着v->T的路径是v->T在原图中的最短路。

这个可以通过反证法证明,前提是原图为无向图。

然而其实这一题我并没有AC。。。不知道是因为复杂度退化了还是常数太大了,一直T。。。

#include<map>#include<cstdio>#include<cstring>#include<algorithm>#define N 200005#define cmin(u,v) (u)>(v)?(u)=(v):0#define mkp(a,b) (1ll*a*N+b)#define reg registerusing namespace std;int in(){    register long long r = 0;    register char c = getchar();    while(c<'0'||c>'9')c = getchar();    while(c>='0'&&c<='9')r = r*10+c-'0', c=getchar();    return r;}char ss[100];inline void out(long long x){    if(x==0) {putchar(48); return;}    char *s=ss;    while(x) *(++s)=x%10, x/=10;    while(s!=ss) putchar((*(s--))+48);    putchar('\n');}map<long long,bool> PathEdge;map<long long,int> PathId;struct node{    int id;    long long dis;    node(){}    node(int a, long long b):id(a),dis(b){}}heap[N<<1];struct Segment_tree{    int l, r;    long long val, lazy;}t[N*5];struct edge{int from,next,to, val;}e[N<<1];const long long INF = 1ll<<61;long long dis[N], ds[N], dt[N], print[N];int n, last[N], ecnt=1, fa[N], fs[N], ft[N], ll[N], rl[N], mapp[N], tcnt, ct[N], ctt, tot;bool vis[N], PathPoint[N];void addedge(int a, int b, int c){    e[++ecnt]=(edge){a,last[a],b,c};    last[a]=ecnt;    PathId[mkp(a,b)]=ecnt;}void heap_add(node x){    heap[++tot]=x;    for(reg int i=tot,j=i>>1;j;i=j,j>>=1)    {        if(heap[j].dis>heap[i].dis)            swap(heap[j],heap[i]);        else break;    }}void heap_pop(){    heap[1]=heap[tot--];    for(reg int i=1,j=i<<1;j<=tot;i=j,j<<=1)    {        if(j<tot&&heap[j].dis>heap[j|1].dis)j|=1;        if(heap[j].dis<heap[i].dis)            swap(heap[j],heap[i]);        else break;     }}void dijk(int s){    memset(vis,0,sizeof(vis));    memset(dis,0x7f,sizeof(dis));    heap_add(node(s,dis[s]=0));    while(tot)    {        int x=heap[1].id;        heap_pop();        if(vis[x])continue;        vis[x]=1;        for(reg int i = last[x]; i; i=e[i].next)        {            int y=e[i].to;            if(vis[y] || dis[x]+e[i].val>=dis[y])continue;            dis[y]=dis[x]+e[i].val;            fa[y]=x;            heap_add(node(y,dis[y]));        }    }}void dijk2(int s, int *fs, long long *ds){    memset(vis,0,sizeof(vis));    memset(ds,0x7f,sizeof(dis));    heap_add(node(s,ds[s]=0));    while(tot)    {        int x=heap[1].id;        heap_pop();        if(vis[x])continue;        vis[x]=1;        if(PathPoint[fa[x]] && (!PathPoint[x]))            fs[x]=fa[x];        else if(PathPoint[x])fs[x]=x;        else fs[x]=fs[fa[x]];        for(reg int i = last[x]; i; i=e[i].next)        {            int y=e[i].to;            if(vis[y] || ds[x]+e[i].val>=ds[y])continue;            ds[y]=ds[x]+e[i].val;            fa[y]=x;            heap_add(node(y,ds[y]));        }    }   }void pushdown(int x){    cmin(t[x<<1].val,t[x].lazy);    cmin(t[x<<1|1].val,t[x].lazy);    cmin(t[x<<1].lazy,t[x].lazy);    cmin(t[x<<1|1].lazy,t[x].lazy);    t[x].lazy=INF;}void merge(int x){    cmin(t[x].val,t[x<<1].val);    cmin(t[x].val,t[x<<1|1].val);}void build(int x, int l, int r){    t[x].l=l; t[x].r=r; t[x].val=INF; t[x].lazy=INF;    if(l==r)return;    int mid=(l+r)>>1;    build(x<<1,l,mid);    build(x<<1|1,mid+1,r);}void update(int x, int l, int r, long long v){    pushdown(x);    if(l<=t[x].l && t[x].r<=r)    {        cmin(t[x].val,v);        cmin(t[x].lazy,v);        return;    }    int mid=(t[x].l+t[x].r)>>1;    if(l<=mid)update(x<<1,l,r,v);    if(mid+1<=r)update(x<<1|1,l,r,v);    merge(x);}void ask(int x){    pushdown(x);    if(t[x].l==t[x].r)    {        print[t[x].l]=t[x].val;        return;    }    ask(x<<1);    ask(x<<1|1);}int main(){    int m, s, t, Q;    n=in();m=in();    for(reg int i = 1, a, b, c; i <= m; i++)    {        a=in(); b=in(); c=in();        addedge(a,b,c);        addedge(b,a,c);    }    s=in(); t=in(); Q=in();    dijk(s);    PathPoint[s]=1;    for(reg int pos = t; fa[pos]; pos=fa[pos])    {        ct[pos]=++ctt;        PathPoint[pos]=1;        PathEdge[mkp(pos,fa[pos])]=1;        PathEdge[mkp(fa[pos],pos)]=1;        ll[pos]=PathId[mkp(fa[pos],pos)]>>1;        rl[fa[pos]]=PathId[mkp(fa[pos],pos)]>>1;        mapp[ll[pos]]=++tcnt;    }    ct[s]=++ctt;    fa[s]=0;dijk2(s,fs,ds);    fa[t]=0;dijk2(t,ft,dt);    build(1,1,ecnt>>1);    for(reg int i = 2; i <= ecnt; i+=2)    {        int a=e[i].from, b=e[i].to, val=e[i].val;        if(!PathEdge[mkp(a,b)])        {            if(mapp[ll[ft[b]]] && mapp[ll[ft[b]]]<=mapp[rl[fs[a]]])update(1,mapp[ll[ft[b]]],mapp[rl[fs[a]]],ds[a]+dt[b]+val);            if(mapp[ll[ft[a]]] && mapp[ll[ft[a]]]<=mapp[rl[fs[b]]])update(1,mapp[ll[ft[a]]],mapp[rl[fs[b]]],ds[b]+dt[a]+val);        }    }    if(dis[t]>=INF)    {        for(;Q--;)            printf("Infinity\n");        return 0;    }    memset(print,0x7f,sizeof(print));    ask(1);    for(;Q--;)    {        int a=in(), b=in();        if(!PathEdge[mkp(a,b)])printf("%lld\n",dis[t]);        else        {            if(ct[a]<ct[b])swap(a,b);            long long ans = print[mapp[ll[ft[b]]]];            if(ans==INF)printf("Infinity\n");            else printf("%lld\n",ans);        }    }}
0 0
原创粉丝点击