Freda的传呼机 倍增LCA+dfs判环

来源:互联网 发布:纽约 攻略 知乎 编辑:程序博客网 时间:2024/06/01 09:42
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>using namespace std;#define maxn 110000int ver[maxn],val[maxn],next[maxn],first[maxn],fa[maxn],a[maxn];int len[maxn],ceng[maxn],f[maxn][16],dis[maxn],dist[maxn],v[maxn],g[maxn],del[maxn];int n,m,tot,t,cnt,i,j,x,y,z,num,now;void add(int x,int y,int z){ver[++tot]=y;val[tot]=z;next[tot]=first[x];first[x]=tot;}void circle(int x,int e){int i,j,y=x;x=ver[e];len[++cnt]=val[e];g[y]=cnt;del[e]=del[e^1]=1;add(x,y,0);add(y,x,0);for(i=fa[y];(y=ver[i^1])!=x;i=fa[y]){len[cnt]+=val[i];g[y]=cnt;del[i]=del[i^1]=1;add(x,y,0);add(y,x,0);}len[cnt]+=val[i];}void dfs(int x){v[x]=++num;for(int i=first[x];i;i=next[i])if(i<=now)if(!v[ver[i]]){fa[ver[i]]=i;dis[ver[i]]=dis[x]+val[i];dfs(ver[i]);}else if(fa[x]!=(i^1)&&v[ver[i]]<v[x])                circle(x,i);}void bfs(){queue<int> q;memset(v,0,sizeof(v));q.push(1);v[1]=1;ceng[1]=1;while(q.size()){x=q.front();q.pop();for(i=first[x];i;i=next[i])if(!del[i]&&!v[y=ver[i]]){ceng[y]=ceng[x]+1;f[y][0]=x;for(j=1;j<15;j++)                    f[y][j]=f[f[y][j-1]][j-1];q.push(y);v[y]=1;}}}void spfa(){memset(dist,0x3f,sizeof(dist));memset(v,0,sizeof(v));queue<int> q;q.push(1);dist[1]=0;v[1]=1;while(q.size()){x=q.front();q.pop();v[x]=0;for(i=first[x];i;i=next[i])if(dist[ver[i]]>dist[x]+val[i]){dist[ver[i]]=dist[x]+val[i];if(!v[ver[i]])                {                    q.push(ver[i]);                    v[ver[i]]=1;                }}}}int lca(int x,int y){if(ceng[x]<ceng[y])        swap(x,y);int i,p=x,q=y;for(i=14;i>=0;i--)if(ceng[f[x][i]]>=ceng[y])            x=f[x][i];if(x==y)        return dist[p]-dist[q];for(i=14;i>=0;i--)if(f[x][i]!=f[y][i])        {            x=f[x][i];            y=f[y][i];        }if(g[x]&&g[x]==g[y]){i=abs(dis[y]-dis[x]);return dist[p]-dist[x]+dist[q]-dist[y]+min(i,len[g[x]]-i);}else return dist[p]+dist[q]-2*dist[f[x][0]];}int main(){cin>>n>>m>>t;for(tot=i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z),add(y,x,z);}spfa();now=tot;dfs(1);bfs();for(i=1;i<=t;i++){scanf("%d%d",&x,&y);printf("%d\n",lca(x,y));}return 0;}/*9 10 21 2 11 4 13 4 12 3 13 7 17 8 27 9 21 5 31 6 45 6 11 95 7*/

0 0
原创粉丝点击