亿些模板【图论】

文章目录

    • 前言
  • 图论模板
    • 最短路-Floyd
    • 最短路-SPFA
    • 最短路-Dij+堆优化
    • 最小生成树-Kruskal
    • 最小生成树-Prim+堆优化
    • 最大匹配-匈牙利算法
    • tarjan求割点
    • tarjan缩点
    • LCA-树上倍增
    • LCA-tarjan+并查集优化
    • 网络流-最大流dinic
    • 网络流-最小费用最大流
    • 负环
    • 虚树
    • 2-SAT
    • Kruskal重构树
    • 静态仙人掌

前言

因为老是懒得打模板的时候老是扣不到自己的标(因为之前的都打得太丑了),所以导致我十分的不爽。便打算开一个模板库。会不断更新的


图论模板

最短路-Floyd

	for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(dis[i][k]+dis[k][j]<dis[i][j])dis[i][j]=dis[i][k]+dis[k][j];

最短路-SPFA

struct edge_node{int to,next,w;
}a[M];
void addl(int x,int y,int w){a[++tot].to=y;a[tot].next=ls[x];a[tot].w=w;ls[x]=tot;
}
void spfa(int s)
{memset(f,0x3f,sizeof(f));q.push(s);v[s]=1;f[s]=0;while(!q.empty()){int x=q.front();q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(f[x]+a[i].w<f[y]){f[y]=f[x]+a[i].w;if(!v[y]){v[y]=1;q.push(y);}}}v[x]=false;}
}

最短路-Dij+堆优化

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=100010,M=200010;
struct node{int pos,dis;bool operator<(const node &x)const{return x.dis<dis;}
};
struct edge_node{int to,next,w;
}a[M];
priority_queue<node> q;
int tot,ls[N],dis[N],n,m,S;
bool v[N];
void addl(int x,int y,int w)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;
}
void dij(int s)
{dis[s]=0;q.push((node){s,0});while(!q.empty()){node tmp=q.top();q.pop();int x=tmp.pos;if(v[x]) continue;v[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(dis[y]>dis[x]+a[i].w){dis[y]=dis[x]+a[i].w;if(!v[y])q.push(node{y,dis[y]});}}}
}
int main()
{scanf("%d%d%d",&n,&m,&S);memset(dis,0x3f,sizeof(dis));for(int i=1;i<=m;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);addl(x,y,w);}dij(S);for(int i=1;i<=n;i++)printf("%d ",dis[i]);
}
}

最小生成树-Kruskal

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=301,M=100010;
struct node{int x,y,w;
}a[M];
int n,m,fa[N],ans,k;
bool cmp(node x,node y)
{return x.w<y.w;}
int find(int x)
{return fa[x]==x?x:find(fa[x]);}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);for(int i=1;i<=n;i++)fa[i]=i;sort(a+1,a+1+m,cmp);for(int i=1;i<=m;i++){int Fa=find(a[i].x),Fb=find(a[i].y);if(Fa!=Fb){fa[Fb]=Fa;ans+=a[i].w;k++;}if(k==n-1) break;}printf("%d %d",k,ans);
}

最小生成树-Prim+堆优化

这个坑先放着,以后再填

最大匹配-匈牙利算法

#include<cstdio>
#include<cstring>
using namespace std;
const int N=1010;
struct line{int to,next;
}a[N*N];
int link[N],n,m,ls[N],tot,s,e;
bool cover[N];
void addl(int x,int y)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
bool find(int x)
{int p=0;for (int i=ls[x];i;i=a[i].next){int y=a[i].to;if (!cover[y]){p=link[y];link[y]=x;cover[y]=true;if (!p || find(p)) return true;link[y]=p;}}return false;
}
int main()
{scanf("%d%d%d",&n,&m,&e);for (int i=1;i<=e;i++){int x,y;scanf("%d%d",&x,&y);if(x>m||y>m) continue;addl(x,y);}for (int i=1;i<=n;i++){memset(cover,false,sizeof(cover));if (find(i)) s++;}printf("%d",s);
}

tarjan求割点

#include<cstdio>
#include<algorithm>
#define N 20100
#define M 100100
using namespace std;
struct node{int to,next;
}a[M*2];
int n,m,tot,dfn[N],low[N],ls[N],cnt,z,root;
bool mark[N],v[N];
void addl(int x,int y)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
void tarjan(int x)
{dfn[x]=low[x]=++cnt;int flag=0;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;v[y]=0;if(!dfn[y]){tarjan(y);low[x]=min(low[x],low[y]);if(dfn[x]<=low[y]){flag++;if((x!=root||flag>1)&&!mark[x])mark[x]=1,z++;}}else low[x]=min(low[x],dfn[y]);}
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);if(x==y) continue;addl(x,y);addl(y,x);}for(int i=1;i<=n;i++)if(!dfn[i]) root=i,tarjan(i);printf("%d\n",z);for(int i=1;i<=n;i++)if(mark[i]) printf("%d ",i);
}

tarjan缩点

#include<cstdio>
#include<stack>
#include<queue>
#include<cstring>
#define N 10000
#define M 100000
using namespace std;
stack<int> Stack;
queue<int> q;
struct line{int to,from,next;
}a[M];
int n,m,x,y,tot,in[N],ls[N],fl[N],cost[N],f[N],maxs,low[N],dfn[N],top,num,gt[N],an[N];
bool ins[N],v[N];
void addl(int x,int y,int tot)
{a[tot].to=y;a[tot].from=x;a[tot].next=ls[x];ls[x]=tot;
}
void tarjan(int x)
{ins[x]=true;dfn[x]=low[x]=++top;Stack.push(x);for (int i=ls[x];i;i=a[i].next)if (!dfn[a[i].to]){tarjan(a[i].to);low[x]=min(low[x],low[a[i].to]);}else if (ins[a[i].to])low[x]=min(low[x],dfn[a[i].to]);if (low[x]==dfn[x]){while (Stack.top()!=x){int y=Stack.top();fl[y]=x;an[x]+=cost[y];//计算强联通权值和Stack.pop();ins[y]=0;}fl[x]=x;an[x]+=cost[x];//计算强联通权值和ins[x]=0;Stack.pop();}
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++) scanf("%d",&cost[i]);for (int i=1;i<=m;i++){scanf("%d%d",&x,&y);addl(x,y,i);//加边}for (int i=1;i<=n;i++)if (!dfn[i])tarjan(i);//求强联通memset(ls,0,sizeof(ls));//去除所有的边的连通(保留值的)for (int i=1;i<=m;i++){x=a[i].from;y=a[i].to;if (fl[x]!=fl[y])//不在强联通中{tot++;addl(fl[x],fl[y],tot);//连边in[fl[y]]++;//统计入度}}
}

LCA-树上倍增

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#define N 600001
using namespace std;
struct line{int to,next,w;
}a[N*5];
int tot,n,m,s,x,y,ls[N],dep[N],f[N][30],dis[N][30],t;
queue<int> q;
inline int readn()
{int X=0,w=0; char c=0;while(c<'0'||c>'9') {w|=c=='-';c=getchar();}while(c>='0'&&c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar();return w?-X:X;
}
inline void addl(int x,int y,int w)
{a[++tot].to=y;a[tot].next=ls[x];a[tot].w=w;ls[x]=tot;
}
inline void bfs(int s)
{q.push(s);dep[s]=1;while(!q.empty()){int x=q.front();q.pop();for (int i=ls[x];i;i=a[i].next){int y=a[i].to;if (dep[y]) continue;q.push(y);f[y][0]=x;dep[y]=dep[x]+1;dis[y][0]=a[i].w;}}t=(int)(log(n)/log(2))+1;for (int j=1;j<=t;j++){for (int i=1;i<=n;i++){f[i][j]=f[f[i][j-1]][j-1];dis[i][j]=min(dis[i][j-1],dis[f[i][j-1]][j-1]);}}
}
inline int LCA(int x,int y)
{if (dep[x]>dep[y]) swap(x,y);for (int i=t;i>=0;i--)if (dep[f[y][i]]>=dep[x]) y=f[y][i];if (x==y) return x;for (int i=t;i>=0;i--)if (f[y][i]!=f[x][i]) {x=f[x][i];y=f[y][i];}return f[x][0];
}
int main()
{n=readn();m=readn();s=readn();for(int i=1;i<n;i++){addl(x=readn(),y=readn(),1);addl(y,x,1);}bfs(s);for(int i=1;i<=m;i++){printf("%d\n",LCA(readn(),readn()));}
}

LCA-tarjan+并查集优化

#include<cstdio>
#include<iostream>
using namespace std;
struct line{int next,to;
}a[20001];
int father[10001],n,m,q,p,v[10001],ans,tot,ls[10001],t,x,y,in[10001];
bool ok;
void addl(int x,int y)//加边
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
int find(int x)//并查集优化
{return x==father[x]?x:find(father[x]);
}
void tarjan(int x)
{v[x]=1;for (int i=ls[x];i;i=a[i].next)//子节点{int y=a[i].to;if (v[y]) continue;tarjan(y);//tarjan一遍father[y]=x;//记录祖先}if (ok) return;//标记已找到if (v[q]==2 && x==p){printf("%d\n",find(q));//输出ok=true;return;}if (v[p]==2 && x==q)///输出{printf("%d\n",find(p));ok=true;return;}v[x]=2;
}
int main()
{scanf("%d",&t);for (;t;t--){scanf("%d",&n);tot=0;ok=0;for (int i=1;i<=n;i++){ls[i]=0;father[i]=i;v[i]=0;in[i]=0;}for (int i=1;i<n;i++){scanf("%d%d",&x,&y);in[y]++;addl(x,y);addl(y,x);}scanf("%d%d",&q,&p);for (int i=1;i<=n;i++)//寻找根if (in[i]==0) tarjan(i);//printf("%d\n",ans);}
}

网络流-最大流dinic

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=10010,M=100010,inf=2147483647/3;
struct node{int to,next,w;
}a[M*2];
int tot=1,n,s,t,m,ans;
int dep[N],ls[N];
queue<int> q;
void addl(int x,int y,int w)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;
}
bool bfs()
{memset(dep,0,sizeof(dep));while(!q.empty()) q.pop();q.push(s);dep[s]=1;while(!q.empty()){int x=q.front();q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!dep[y]&&a[i].w){dep[y]=dep[x]+1;if(y==t) return true;q.push(y);}}}return false;
}
int dinic(int x,int flow)
{int rest=0,k;if(x==t) return flow;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(dep[x]+1==dep[y]&&a[i].w){rest+=(k=dinic(y,min(a[i].w,flow-rest)));a[i].w-=k;a[i^1].w+=k;if(rest==flow) return flow;}}if(!rest) dep[x]=0;return rest;
}
void netflow()
{while(bfs())ans+=dinic(s,inf);
}
int main()
{scanf("%d%d%d%d",&n,&m,&s,&t);for(int i=1;i<=m;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);addl(x,y,w);}netflow();printf("%d",ans);
}

网络流-最小费用最大流

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=5010,M=50010,inf=2147483647/3;
struct node{int to,w,c,next;
}a[M*2];
queue<int>q;
int f[N],mf[N],ls[N],pre[N];
int n,s,e,tot,m,anscost,ansflow;
bool v[N];
void addl(int x,int y,int w,int c)
{a[++tot].w=w;a[tot].to=y;a[tot].c=c;a[tot].next=ls[x];ls[x]=tot;a[++tot].w=0;a[tot].to=x;a[tot].c=-c;a[tot].next=ls[y];ls[y]=tot;
}
bool spfa()
{memset(f,0x3f,sizeof(f));memset(v,0,sizeof(v));memset(mf,0,sizeof(mf));q.push(s);f[s]=0;v[s]=1;mf[s]=inf;while(!q.empty()){int x=q.front();q.pop();v[x]=0;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(f[x]+a[i].c<f[y]&&a[i].w){f[y]=f[x]+a[i].c;mf[y]=min(mf[x],a[i].w);pre[y]=i;if(!v[y]){v[y]=true;q.push(y);}}}}return f[e]<=2147483647/3;
}
int updata()
{int x=e;while(x!=s){a[pre[x]].w-=mf[e];a[pre[x]^1].w+=mf[e];x=a[pre[x]^1].to;}anscost+=f[e]*mf[e];ansflow+=mf[e];
}
void netflow()
{while(spfa())updata();
}
int main()
{tot=1;scanf("%d%d%d%d",&n,&m,&s,&e);for(int i=1;i<=m;i++){int x,y,w,c;scanf("%d%d%d%d",&x,&y,&w,&c);addl(x,y,w,c);}netflow();printf("%d %d",ansflow,anscost);
}

负环

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int N=2100,M=3100;
struct node{int to,next,w;
}a[M*2];
queue<int> q;
int n,m,tot,ls[N],f[N],cnt[N],T;
bool v[N];
void addl(int x,int y,int w)
{a[++tot].to=y;a[tot].next=ls[x];a[tot].w=w;ls[x]=tot;
}
bool spfa()
{memset(f,0x3f,sizeof(f));memset(cnt,0,sizeof(cnt));q.push(1);cnt[1]=1;f[1]=0;v[1]=1;while(!q.empty()){int x=q.front();v[x]=0;q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(f[x]+a[i].w<f[y]){f[y]=f[x]+a[i].w;cnt[y]=cnt[x]+1;if(cnt[y]>=n&&a[i].w<0)return true;if(!v[y]){v[y]=1;q.push(y);}}} }return false;
}
int main()
{scanf("%d",&T);while(T--){ memset(ls,0,sizeof(ls));tot=0;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);addl(x,y,w);if(w>=0) addl(y,x,w);}if(spfa()) printf("YE5");else printf("N0");putchar('\n');}
}

虚树

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110000;
struct node{int to,next;
}a[2*N];
int n,siz[N],dep[N],son[N],top[N],fa[N];
int tot,ls[N],p[N],ans,cnt,s[N],q,dfn[N],num;
void adde(int x,int y)
{if(x==y) return;a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
void dfs1(int x)
{siz[x]=1;dfn[x]=++num; for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x]) continue;dep[y]=dep[x]+1;fa[y]=x;dfs1(y);siz[x]+=siz[y];if(siz[y]>siz[son[x]])son[x]=y; }
}
void dfs2(int x,int fa)
{if(son[x]){top[son[x]]=top[x];dfs2(son[x],x);}for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa||y==son[x]) continue;top[y]=y;dfs2(y,x);}
}
int LCA(int x,int y)
{while(top[x]!=top[y])if(dep[top[x]]<dep[top[y]]) y=fa[top[y]];else x=fa[top[x]];if(dep[x]<dep[y]) return x;return y;
}
void ins(int x)
{if(!cnt){s[++cnt]=x;return;}int lca=LCA(s[cnt],x);while(cnt>1&&dep[lca]<dep[s[cnt-1]]){adde(s[cnt-1],s[cnt]),cnt--;}if(dep[lca]<dep[s[cnt]]) adde(lca,s[cnt--]);if((!cnt)||(s[cnt]!=lca)) s[++cnt]=lca;s[++cnt]=x;
}
void dp(int x)
{if(siz[x]){for(int i=ls[x];i;i=a[i].next){int y=a[i].to;dp(y);if(siz[y]){siz[y]=0;ans++;}}}else{for(int i=ls[x];i;i=a[i].next){int y=a[i].to;dp(y);siz[x]+=siz[y];siz[y]=0;}if(siz[x]>1){ans++;siz[x]=0;}}ls[x]=0;
}
bool cmp(int x,int y)
{return dfn[x]<dfn[y];}
int main()
{scanf("%d",&n);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);adde(x,y);adde(y,x);}dfs1(1);top[1]=1;dfs2(1,1);tot=0;memset(siz,0,sizeof(siz));memset(ls,0,sizeof(ls));scanf("%d",&q);while(q--){int k;cnt=0;ans=0;scanf("%d",&k);p[0]=1;for(int i=1;i<=k;i++){scanf("%d",&p[i]);siz[p[i]]++;}for(int i=1;i<=k;i++)if(siz[fa[p[i]]]){puts("-1");p[0]=0;break;}if(!p[0]){for(int i=1;i<=k;i++)siz[p[i]]--;continue;}sort(p+1,p+1+k,cmp);if(p[1]!=1) s[++cnt]=1;for(int i=1;i<=k;i++) ins(p[i]);while(cnt>1) adde(s[cnt-1],s[cnt]),cnt--;dp(1);siz[1]=tot=0;printf("%d\n",ans);}
}

2-SAT

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int N=2e6+10;
struct node{int to,next;
}a[N*2];
int n,m,tot,cnt,num,ls[N];
int dfn[N],low[N],color[N];
bool ins[N];
stack<int> S;
void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void tarjan(int x){dfn[x]=low[x]=++cnt;S.push(x);ins[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);else if(ins[y]) low[x]=min(low[x],dfn[y]);}if(low[x]==dfn[x]){++num;while(S.top()!=x){ins[S.top()]=0;color[S.top()]=num;S.pop();}color[S.top()]=num;ins[S.top()]=0;S.pop();}return;
}
int main()
{scanf("%d%d",&n,&m);for(int k=1;k<=m;k++){int i,a,j,b;scanf("%d%d%d%d",&i,&a,&j,&b);addl(i+a*n,j+(!b)*n);addl(j+b*n,i+(!a)*n);}for(int i=1;i<=n*2;i++)if(!dfn[i])tarjan(i);for(int i=1;i<=n;i++)if(color[i]==color[i+n]){printf("IMPOSSIBLE");return 0;}printf("POSSIBLE\n");for(int i=1;i<=n;i++)printf("%d ",color[i]<color[i+n]);
}

Kruskal重构树

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+10;
struct node{int x,y,w; 
}e[N];
struct edge_node{int to,next;
}a[N];
int n,m,k,tot,cnt,root,ls[N],val[N];
int top[N],dep[N],siz[N],son[N],fa[N];
void addl(int x,int y)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
bool cmp(node x,node y)
{return x.w<y.w;}
int find(int x)
{return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
void dfs1(int x)
{for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x]) continue;dep[y]=dep[x]+1;fa[y]=x;dfs1(y);siz[x]+=siz[y];if(siz[y]>siz[son[x]])son[x]=y;}
}
void dfs2(int x)
{if(son[x]){top[son[x]]=top[x];dfs2(son[x]);}for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x]||y==son[x]) continue;top[y]=y;dfs2(y);}
}
int LCA(int x,int y)
{while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);x=fa[top[x]];}if(dep[x]<dep[y]) return x;else return y;
}
int main()
{scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);for(int i=1;i<=n+m;i++)fa[i]=i;sort(e+1,e+1+m,cmp);cnt=n;for(int i=1;i<=m;i++){int fx=find(e[i].x),fy=find(e[i].y);if(fx!=fy){fa[fy]=fa[fx]=++cnt;addl(cnt,fx);addl(cnt,fy);addl(fx,cnt);addl(fy,cnt);val[cnt]=e[i].w;}}root=find(1);dfs1(root);top[root]=root;dfs2(root);for(int i=1;i<=k;i++){int x,y;scanf("%d%d",&x,&y);printf("%d\n",val[LCA(x,y)]);}
}

静态仙人掌

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e4+10,K=18;
struct node{int to,next,w;
}a[N*2],e[N*2];
int n,m,q,tot,num,cnt;
int f[N][K],s[N],val[N],dep[N],dis[N];
int ls[N],rs[N],dfn[N],low[N];
void addl(int x,int y,int w){a[++tot].to=y;a[tot].next=ls[x];a[tot].w=w;ls[x]=tot;
}
void adde(int x,int y,int w){e[++tot].to=y;e[tot].next=rs[x];e[tot].w=w;rs[x]=tot;
}
void circle(int x,int y,int w){num++;int now=y,sum=w;while(now!=f[x][0]){s[now]=sum;sum+=val[now];now=f[now][0];}sum=s[num]=s[x];s[x]=0;now=y;int Dis;while(now!=f[x][0]){Dis=min(s[now],sum-s[now]);adde(num,now,Dis);adde(now,num,Dis);now=f[now][0];}return;
}
void tarjan(int x){dfn[x]=low[x]=++cnt;int flag=0;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==f[x][0])continue;if(!dfn[y]){f[y][0]=x;val[y]=a[i].w;tarjan(y);low[x]=min(low[x],low[y]);}else low[x]=min(low[x],dfn[y]);if(low[y]<=dfn[x])continue;adde(x,y,a[i].w);adde(y,x,a[i].w);}for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(x==f[y][0]||dfn[x]>=dfn[y])continue;circle(x,y,a[i].w);}return;
}
void dfs(int x,int fa){for(int i=rs[x];i;i=e[i].next){int y=e[i].to;if(y==fa)continue;dep[y]=dep[x]+1;dis[y]=dis[x]+e[i].w;f[y][0]=x;dfs(y,x);}return;
}
int Get_dis(int x,int y){int u=x,v=y;if(dep[x]>dep[y])swap(x,y);for(int i=K-1;i>=0;i--)if(dep[f[y][i]]>=dep[x])y=f[y][i];int lca;if(x!=y){for(int i=K-1;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];lca=f[x][0];}else lca=x;if(lca<=n)return dis[u]+dis[v]-dis[lca]*2;else {int ans=dis[u]-dis[x]+dis[v]-dis[y];return ans+min(s[lca]-abs(s[x]-s[y]),abs(s[x]-s[y]));}
}
int main()
{scanf("%d%d%d",&n,&m,&q);num=n;for(int i=1;i<=m;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);addl(x,y,w);addl(y,x,w);}tot=0;tarjan(1);dep[1]=1;dfs(1,0);for(int i=1;i<K;i++)for(int j=1;j<=num;j++)f[j][i]=f[f[j][i-1]][i-1]; for(int i=1;i<=q;i++){int x,y;scanf("%d%d",&x,&y);printf("%d\n",Get_dis(x,y));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中间件中渲染Razor视图

前言 上一篇文章《ASP.NET Core 奇技淫巧&#xff08;1&#xff09;&#xff1a;中间件实现服务端静态化缓存》中介绍了中间件的使用方法、以及使用中间件实现服务端静态化缓存的功能。本系列文章取名“奇技淫巧”不是没道理的&#xff0c;因为这写技巧都是我最近在做的公司实际…

解决idea启动项目报错:Unable to open debugger port(127.0.0.1:60157):java.net.SocketExceptionsocket closed

转载自 解决idea启动项目报错:Unable to open debugger port(127.0.0.1:60157):java.net.SocketException"socket closed 1.问题描述: 工作当中免不了要重启服务,debug模式下偶尔启动项目,却启动失败报错: Unable to open debugger port (127.0.0.1:60157): java.net.S…

python3如何连接mysql数据库

原本连接数据库用的是mysql_python&#xff0c;但发现无论怎么安装都装不上去&#xff0c;pip和手动安装都失败了 后来才知道用pymysql才是3版本以后最好适用的 命令 pip3 install PyMySQL连接数据库 import pymysql conn pymysql.connect(localhost, root, 123456)

亿些模板【数据结构】

文章目录前言数据结构模板并查集带权并查集堆hash表RMQ线段树树状数组树状数组区间修改版分块主席树有旋TreapSplay替罪羊树文艺平衡树-Splay点分治树链剖分可持久化并查集LCT左偏树前言 因为老是懒得打模板的时候老是扣不到自己的标(因为之前的都打得太丑了)&#xff0c;所以…

下一个计划 : .NET/.NET Core应用性能管理

前言 最近几个月一直在研究开源的APM和监控方案&#xff0c;并对比使用了Zipkin,CAT,Sky-walking,PinPoint(仅对比,未实际部署),Elastic APM,TICK Stack,Prometheus等开源产品&#xff0c;其中不乏功能强大的监控和追踪系统&#xff0c;但它们都对.NET/.NET Core没有支持或支持…

详解proxy_pass、upstream与resolver

转载自 详解proxy_pass、upstream与resolver 应用场景 这里列举几个应用场景&#xff0c;下文会针对这几个场景并结合代码进行分析。 &#xff08;1&#xff09;proxy_pass upstream upstream foo.example.com {server 127.0.0.1:8001;}server {listen 80;server_na…

如何用python将srt文件转化成数组形式

原srt文件 0 00:00:00,150 --> 00:00:11,430 Fighting this pandemic needs political commitment and commitment at the highest level possible and the Presidents commitment.1 00:00:11,431 --> 00:00:16,020 you have what it is in it and the would it have se…

架构演化:云原生时代开启之系列一演化篇

信息技术从出现伊始到渐成主流&#xff0c;其趋势经历了软件、开源和云三个阶段&#xff1a; 软件改变世界。纵观人类社会漫长的发展历程&#xff0c;农耕时代、工业时代与信息时代可谓是三个明显分水岭&#xff0c;每个时代人类涉及的领域范畴均喷井式增长。作为信息时代最重要…

mysql出现unblock with 'mysqladmin flush-hosts'

转载自 mysql出现unblock with mysqladmin flush-hosts 朋友发来消息&#xff0c;说一个系统应用登录的时候提示连接超时&#xff0c;让帮忙处理一下。 问他应用和数据库是否都正常&#xff0c;回复说数据库好像没有问题&#xff0c;但是应用日志报无法连接数据库。 数据库版…

laravel部署到服务器显示Permission denied

解决这个问题可以先cd到项目根目录中 依次输入以下两个命令 find storage -type d -exec chmod 777 {} \;find storage -type f -exec chmod 777 {} \;不报错就证明成功了

亿些模板【数论数学】

文章目录前言数论数学模板GCDexgcd快速幂线性推逆元线性推逆元(非连续)逆元求组合数矩阵乘法线性筛素数-埃氏筛线性筛素数-线性筛线性筛欧拉-埃氏筛线性求欧拉龟速乘FFTNTT分治FFT多项式求逆扩展中国剩余定理Lucas定理高斯消元BSGS拉格朗日插值二次剩余线性基杜教筛前言 因为老…

基于OIDC(OpenID Connect)的SSO

在[认证授权]系列博客中&#xff0c;分别对OAuth2和OIDC在理论概念方面进行了解释说明&#xff0c;其间虽然我有写过一个完整的示例&#xff08;https://github.com/linianhui/oidc.example&#xff09;&#xff0c;但是却没有在实践方面做出过解释。在这里新开一个系列博客&am…

Consul集群搭建

转载自 Consul集群搭建 概述 作为服务发现的几种产品&#xff0c;比较可以查看这里。Consul官方也提供了几种产品之间的比较&#xff0c;点击查看。 服务发现产品 Consul有很多组件&#xff0c;但总体来说&#xff0c;它是一个发现和配置服务工具&#xff0c;特性&#xff…

js遍历对象的key和value

如果想要得到数组的键值对&#xff0c;可以用以下方法 object {"name":"kejin","age":"18"}for(var index in object){console.log(index);console.log(object[index]); }

亿些模板【字符串+其他】

文章目录前言其他快读快输卡常DataMakerDataMakerDataMaker字符串模板KMP字符串hashTrie最小表示法ManacherAC自动机SASAM广义SAMPAM其他模板凸包模拟退火前言 因为老是懒得打模板的时候老是扣不到自己的标(因为之前的都打得太丑了)&#xff0c;所以导致我十分的不爽。便打算开…

使用Identity Server 4建立Authorization Server (6) - js(angular5) 客户端

预备知识: 学习Identity Server 4的预备知识 第一部分: 使用Identity Server 4建立Authorization Server (1) 第二部分: 使用Identity Server 4建立Authorization Server (2) 第三部分: 使用Identity Server 4建立Authorization Server (3) 第四部分: 使用Identity Server 4建立…

SpringBoot整合kafka(实现producer和consumer)

转载自 SpringBoot整合kafka(实现producer和consumer) 在Windows环境下安装运行Kafka&#xff1a;https://www.jianshu.com/p/d64798e81f3b 本文代码使用的是Spring Boot 2.1.1.RELEASE 版本 <parent><groupId>org.springframework.boot</groupId><art…

js的字符串和变量拼接

使用反引号拼接字符串和变量 let count 1 name 用户${count} console.log(name);注意是反引号不是引号&#xff0c;反引号是Esc下面的一个按键

ASP.NET Core 认证与授权[7]:动态授权

基于资源的授权 有些场景下&#xff0c;授权需要依赖于要访问的资源&#xff0c;例如&#xff1a;每个资源通常会有一个创建者属性&#xff0c;我们只允许该资源的创建者才可以对其进行编辑&#xff0c;删除等操作&#xff0c;这就无法通过[Authorize]特性来指定授权了。因为授…

maven中scope属性的

转载自 maven中scope属性的 Dependency Scope 在POM 4中&#xff0c;<dependency>中还引入了<scope>&#xff0c;它主要管理依赖的部署。目前<scope>可以使用5个值&#xff1a; * compile&#xff0c;缺省值&#xff0c;适用于所有阶段&#xff0c;会随着…