BZOJ2125: 最短路

一个晚上的Debug….
仙人掌

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<queue>
using namespace std;

struct Chain
{
    Chain *next;
    int u,w;
}*Head[20001],*Head2[30001];

inline void Add(int u,int v,int w){Chain *tp=new Chain;tp->next=Head[u];tp->u=v;tp->w=w;Head[u]=tp;}
inline void Add2(int u,int v,int w){Chain *tp=new Chain;tp->next=Head2[u];tp->u=v;tp->w=w;Head2[u]=tp;}
int n,m;
char c;
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
int DFSdis[20001];
int Dep1[20001],Dep2[30001],f1[20001][21],f2[30001][21];
int Dfs[20001],low[20001],con;
int R;
int stack[20001];
int dis[20001],pre[20001];
bool vis[20001];
queue<int>Q;
inline int spfa(int s)
{
    dis[s]=0;
    Q.push(s);
    vis[s]=true;
    while(!Q.empty())
    {
        int u=Q.front();
        for(Chain *tp=Head[u];tp;tp=tp->next)
            if((dis[tp->u]==0&&tp->u!=s)||dis[tp->u]>dis[u]+tp->w)
                {dis[tp->u]=dis[u]+tp->w;if(!vis[tp->u])vis[tp->u]=true,Q.push(tp->u);pre[tp->u]=u;}
         vis[u]=false;
        Q.pop();
    }
}
Chain *Rev[10001];
void dfs(int u,int f)
{
    f1[u][0]=f;
    Dep1[u]=Dep1[f]+1;
    stack[Dfs[u]=low[u]=++con]=u;
    for(Chain *tp=Head[u];tp;tp=tp->next) 
        if(tp->u!=f)
        {

            if(Dfs[tp->u])
                    low[u]=min(Dfs[tp->u],low[u]),Rev[u]=tp;
            else 
            {
            DFSdis[tp->u]=DFSdis[u]+tp->w,dfs(tp->u,u),low[u]=min(low[u],low[tp->u]);
            if(Dfs[u]==low[tp->u])
            {
                f2[++R][0]=u;Add2(u,R,1),Add2(R,u,1);
                for(int i=Dfs[tp->u];i<=con;i++)
                    f2[stack[i]][0]=R,Add2(R,stack[i],1),Add2(stack[i],R,1);
                dis[R]=Rev[stack[con]]->w+DFSdis[stack[con]]-DFSdis[u];
                con=Dfs[tp->u]-1;
            }
            else if(low[tp->u]>Dfs[u])Add2(u,tp->u,1),Add2(tp->u,u,1);

            }
        }
    if(Dfs[u]==low[u])con--;
}
void dfs2(int u,int f)
{
    f2[u][0]=f;
    Dep2[u]=Dep2[f]+1;
    for(Chain *tp=Head2[u];tp;tp=tp->next) 
        if(tp->u!=f)
        //if(!Dep2[tp->u])
        dfs2(tp->u,u);
}

inline int Up1(int x,int d)
{
   int y=Dep1[x]-d,i;
   while(Dep1[x]^y)
    {
      for(i=0;Dep1[f1[x][i+1]]>=y&&i<20;i++);
      x=f1[x][i];
    }
return x;
}


inline int LCA1(int x,int y)
{
  if(Dep1[x]<Dep1[y])swap(x,y);
  int i;
   while(Dep1[x]^Dep1[y])
    {
      for(i=0;Dep1[f1[x][i+1]]>=Dep1[y]&&i<20;i++);
      x=f1[x][i];
    }
    while(x^y)
    {
      for(i=0;f1[x][i+1]!=f1[y][i+1]&&i<20;i++);
      x=f1[x][i],y=f1[y][i];
    }
return x;
}

int Up2(int x,int d)
{
   int y=Dep2[x]-d,i;
   while(Dep2[x]^y)
    {
      for(i=0;Dep2[f2[x][i+1]]>=y&&i<20;i++);
      x=f2[x][i];
    }
return x;
}
inline int LCA2(int x,int y)
{
  if(Dep2[x]<Dep2[y])swap(x,y);
  int i;
   while(Dep2[x]^Dep2[y])
    {
      for(i=0;Dep2[f2[x][i+1]]>=Dep2[y]&&i<20;i++);
      x=f2[x][i];
    }
    while(x^y)
    {
      for(i=0;f2[x][i+1]!=f2[y][i+1]&&i<20;i++);
      x=f2[x][i],y=f2[y][i];
    }
return x;
}



int main()
{

    int i,j,k,l,Q;
    read(n),read(m),read(Q);
    for(i=1;i<=m;i++)
      read(j),read(k),read(l),Add(j,k,l),Add(k,j,l);
    R=n;
    dfs(1,1);
    for(int i=1;i<=20;i++)
        for(int j=1;j<=n;j++)f1[j][i]=f1[f1[j][i-1]][i-1];
    dfs2(1,1);
    for(int i=1;i<=20;i++)
        for(int j=1;j<=R;j++)f2[j][i]=f2[f2[j][i-1]][i-1];
    spfa(1);
    int pos=0;
    while(Q--)
    {
        pos++;
        read(j),read(k);
        int f,fj,fk,F2;
        if((f=LCA1(j,k))==(F2=LCA2(j,k)))
            printf("%d\n",dis[j]+dis[k]-2*dis[f]);
        else
        {fj=Up2(j,Dep2[j]-Dep2[F2]-1);fk=Up2(k,Dep2[k]-Dep2[F2]-1);
        printf("%d\n",dis[j]+dis[k]-dis[fj]-dis[fk]+min(abs(DFSdis[fj]-DFSdis[fk]),dis[F2]-abs(DFSdis[fj]-DFSdis[fk])));}
    }
}
发布了237 篇原创文章 · 获赞 1 · 访问量 12万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览