树上问题&图论模板整理
去除过水的模板,包括但不限于dijkstra(甚至堆优化都被过滤了)、SPFA、kruskal、拓扑排序等。
欧拉回路:http://uoj.ac/problem/117
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+;
int n,m,tp,cnt,ecnt=,in[N],ou[N],vis[N],hd[N],v[N],nxt[N],ans[N];
void adde(int x,int y){v[++ecnt]=y,nxt[ecnt]=hd[x],hd[x]=ecnt;}
void dfs(int u)
{
for(int &i=hd[u];i;i=nxt[i])
{
int y=v[i],j=i;
if(!vis[j>>])vis[j>>]=,dfs(y),ans[++cnt]=j;
}
}
int main()
{
scanf("%d%d%d",&tp,&n,&m);
int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y),adde(x,y);
if(tp==)adde(y,x),in[x]++,in[y]++;
else ecnt++,in[y]++,ou[x]++;
}
if(tp==){for(int i=;i<=n;i++)if(in[i]&){puts("NO");return ;}}
else for(int i=;i<=n;i++)if(in[i]!=ou[i]){puts("NO");return ;}
dfs(x);
if(cnt!=m)puts("NO");
else{
puts("YES");
for(int i=cnt;i;i--)printf("%d ",(ans[i]&)?-(ans[i]>>):(ans[i]>>));
}
}
混合图的欧拉路:https://www.lydsy.com/JudgeOnline/problem.php?id=2095
#include<bits/stdc++.h>
using namespace std;
const int N=,M=1e6+;
int n,m,mn=1e9,mx,cnt,tot,S=,T=,hd[N],v[M],nxt[M],cap[M],lv[N];
int st[N],ed[N],w1[N],w2[N],du[N],q[N];
void add(int x,int y,int z)
{
v[++cnt]=y,nxt[cnt]=hd[x],cap[cnt]=z,hd[x]=cnt;
v[++cnt]=x,nxt[cnt]=hd[y],cap[cnt]=,hd[y]=cnt;
}
bool bfs()
{
int qs=,qe=;
memset(lv,-,sizeof lv);
lv[q[]=S]=;
while(qs<qe)
{
int u=q[qs++];
if(u==T)break;
for(int i=hd[u];i;i=nxt[i])
if(cap[i]&&lv[v[i]]==-)lv[v[i]]=lv[u]+,q[qe++]=v[i];
}
return lv[T]!=-;
}
int dfs(int u,int low)
{
if(u==T)return low;
int sum=,tmp;
for(int i=hd[u];i;i=nxt[i])
if(cap[i]&&lv[v[i]]==lv[u]+)
{
tmp=dfs(v[i],min(low,cap[i]));
low-=tmp,sum+=tmp;
cap[i]-=tmp,cap[i^]+=tmp;
}
if(!sum)lv[u]=-;
return sum;
}
int dinic()
{
int ret=;while(bfs())ret+=dfs(S,1e9);
return ret;
}
bool check(int mid)
{
memset(hd,,sizeof hd);
memset(du,,sizeof du);
tot=,cnt=;
for(int i=;i<=m;++i)
{
if(w1[i]<=mid)--du[st[i]],++du[ed[i]];
if(w2[i]<=mid)add(ed[i],st[i],);
}
for(int i=;i<=n;++i)
if(du[i]>)tot+=du[i]/,add(S,i,du[i]/);else if(du[i]<)add(i,T,-du[i]/);
for(int i=;i<=n;++i)if(du[i]&)return ;
if(dinic()==tot)return ;
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d%d",&st[i],&ed[i],&w1[i],&w2[i]);
if(w1[i]>w2[i])swap(w1[i],w2[i]),swap(st[i],ed[i]);
mn=min(mn,w1[i]),mx=max(mx,w2[i]);
}
int l=mn,r=mx,ans=mx+;
while(l<=r)
{
int mid=l+r>>;
if(check(mid))ans=mid,r=mid-;
else l=mid+;
}
if(ans==mx+)puts("NIE");else printf("%d",ans);
}
强连通分量:https://www.lydsy.com/JudgeOnline/problem.php?id=1654
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e4+;
int n,m,cnt,v[N*],next[N*],head[N];
int q[N],top,low[N],dfn[N],sum[N],scc,ans;
bool vis[N];
void add(int x,int y)
{v[++cnt]=y;next[cnt]=head[x];head[x]=cnt;}
void tarjan(int u)
{
low[u]=dfn[u]=++cnt;
q[++top]=u;vis[u]=;
for(int i=head[u];i;i=next[i])
if(!dfn[v[i]])
{
tarjan(v[i]);
low[u]=min(low[u],low[v[i]]);
}
else if(vis[v[i]])
low[u]=min(low[u],dfn[v[i]]);
int now=;
if(low[u]==dfn[u])
{
scc++;
while(now!=u)
{
now=q[top--];
vis[now]=;
sum[scc]++;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
cnt=;
for(int i=;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int i=;i<=scc;i++)
if(sum[i]>)
ans++;
printf("%d",ans);
}
求割点:https://www.luogu.org/problemnew/show/P3388
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+;
int n,m,cnt=,ans,v[N],nxt[N],hd[N],low[N],dfn[N],cut[N];
void add(int x,int y){v[++cnt]=y,nxt[cnt]=hd[x],hd[x]=cnt;}
void tarjan(int u,int pre)
{
int sum=;bool flag=;
dfn[u]=low[u]=++cnt;
for(int i=hd[u];i;i=nxt[i])
if(i!=(pre^))
{
if(!dfn[v[i]])
{
sum++;
tarjan(v[i],i);
low[u]=min(low[u],low[v[i]]);
if(low[v[i]]>=dfn[u])flag=;
}
else low[u]=min(low[u],dfn[v[i]]);
}
if(!pre&&sum>||pre&&flag)cut[u]=,ans++;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y;i<=m;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
cnt=;
for(int i=;i<=n;i++)if(!dfn[i])tarjan(i,);
printf("%d\n",ans);
for(int i=;i<=n;i++)if(cut[i])printf("%d ",i);
}
圆方树:https://www.luogu.org/problemnew/show/P4630
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+;
vector<int>G1[N],G2[N];
int n,m,tot,sum,tim,top,low[N],dfn[N],q[N],sz[N],val[N];
ll ans;
void tarjan(int u)
{
dfn[u]=low[u]=++tim,q[++top]=u;
sz[u]=,val[u]=-;
for(int i=;i<G1[u].size();i++)
if(!dfn[G1[u][i]])
{
int v=G1[u][i];
tarjan(v),low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])
{
G2[u].push_back(++tot),val[tot]=;
int x=;
do{
x=q[top--],G2[tot].push_back(x);
sz[tot]+=sz[x],val[tot]++;
}while(x!=v);
sz[u]+=sz[tot];
}
}
else low[u]=min(low[u],dfn[G1[u][i]]);
}
void dfs(int u)
{
if(u<=n)ans+=1ll*(sum-)*val[u];
ans+=1ll*(sum-sz[u])*sz[u]*val[u];
for(int i=;i<G2[u].size();i++)
ans+=1ll*(sum-sz[G2[u][i]])*sz[G2[u][i]]*val[u],dfs(G2[u][i]);
}
int main()
{
scanf("%d%d",&n,&m),tot=n;
for(int i=,x,y;i<=m;i++)scanf("%d%d",&x,&y),G1[x].push_back(y),G1[y].push_back(x);
for(int i=;i<=n;i++)if(!dfn[i])tarjan(i),sum=sz[i],dfs(i);
printf("%lld",ans);
}
floyd判圈法:https://codeforces.com/gym/101252/problem/D
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e7;
ll a,b,c,s,r,x,y;
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
cin>>a>>b>>c;
x=y=;
while(s<N)
{
s++;
y=(a*y+y%b)%c,y=(a*y+y%b)%c;
x=(a*x+x%b)%c;
if(x==y)break;
}
if(x!=y){puts("-1");return ;}
while(r<N)
{
r++;
y=(a*y+y%b)%c;
if(x==y)break;
}
if(x!=y){puts("-1");return ;}
s=,y=;
while(x!=y&&s<N)
{
s++;
y=(a*y+y%b)%c;
x=(a*x+x%b)%c;
}
s+=r;
if(x==y&&s<=N)cout<<s;
else puts("-1");
return ;
}
kruskal重构树:NOI2018归程
#include<bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N=2e6;
struct path{int u,v,w;}a[N];
struct edge{int v,nxt;ll w;}e[N];
int n,m,cnt,tot,hd[N],fa[N],f[N][],val[N],Q,K,S;
ll d[N],minv[N];
bool vis[N];
priority_queue<pair<ll,int> >q;
bool cmp(path a,path b){return a.w>b.w;}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void add(int x,int y,ll z){e[++cnt]=(edge){y,hd[x],z};hd[x]=cnt;}
void dijkstra()
{
memset(vis,,sizeof vis);
for(int i=;i<=*n;i++)d[i]=1e17;
q.push(mp(,));
while(!q.empty())
{
int u=q.top().second;q.pop();
if(vis[u])continue;
vis[u]=;
for(int i=hd[u];i;i=e[i].nxt)
if(d[u]+e[i].w<d[e[i].v]&&!vis[e[i].v])
d[e[i].v]=d[u]+e[i].w,q.push(mp(-d[e[i].v],e[i].v));
}
}
void dfs(int u)
{
minv[u]=d[u];
for(int i=hd[u];i;i=e[i].nxt)
{
f[e[i].v][]=u;
dfs(e[i].v);
minv[u]=min(minv[u],minv[e[i].v]);
}
}
void kruskal()
{
memset(hd,,sizeof hd);cnt=;
tot=n;
sort(a+,a+m+,cmp);
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=m;i++)
{
int x=find(a[i].u),y=find(a[i].v);
if(x!=y)
{
val[++tot]=a[i].w;
fa[x]=fa[y]=fa[tot]=tot;
add(tot,x,);add(tot,y,);
}
}
dfs(tot);
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
memset(hd,,sizeof hd);
memset(f,,sizeof f);
cnt=;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int x,y,w,h;
scanf("%d%d%d%d",&x,&y,&w,&h);
add(x,y,w);add(y,x,w);
a[i]=(path){x,y,h};
}
dijkstra();
kruskal();
for(int j=;(<<j)<=tot;j++)
for(int i=;i<=tot;i++)
f[i][j]=f[f[i][j-]][j-];
scanf("%d%d%d",&Q,&K,&S);
ll ans=;
while(Q--)
{
int vi,pi;
scanf("%d%d",&vi,&pi);
vi=(vi+K*ans-)%n+;
pi=(pi+K*ans)%(S+);
for(int j=;~j;j--)
if(f[vi][j]&&val[f[vi][j]]>pi)
vi=f[vi][j];
printf("%lld\n",ans=minv[vi]);
}
}
}
基环树:NOIP2018旅行O(nlogn)
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+;
int n,m,top,k,cnt,cut,a[N],b[N],cir[N],s[N],g[N],vis[N];
vector<int>v[N];
inline int read()
{
int x=,w=;
char ch=;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while(isdigit(ch))x=(x<<)+(x<<)+(ch^),ch=getchar();
return w?-x:x;
}
void dfs(int u,int fa)
{
a[++top]=u;
for(int i=;i<v[u].size();++i)if(v[u][i]!=fa)dfs(v[u][i],u);
}
void getcir(int x,int fa)
{
s[++top]=x;
vis[x]=;
int sz=v[x].size();
for(int i=;i<sz;++i)
if(v[x][i]!=fa)
{
if(vis[v[x][i]])
{
k=;
while(s[top]!=v[x][i])g[++cnt]=s[top--];
g[++cnt]=v[x][i];
return;
}
getcir(v[x][i],x);
if(k)return;
}
vis[s[top--]]=;
}
void dfs2(int x,int k,int fa)
{
a[++top]=x,vis[x]=;
int sz=v[x].size()-;
for(int i=;i<=sz;++i)b[i]=v[x][i];
v[x].clear();
for(int i=;i<=sz;++i)
if(!vis[b[i]])v[x].push_back(b[i]);
sz=v[x].size()-;
for(int i=;i<=sz;++i)
if(!vis[v[x][i]])
{
if(i==sz&&cir[v[x][i]]&&!cut&&v[x][i]>k&&cir[fa]){cut=;return;}
if(i<sz-)dfs2(v[x][i],v[x][i+],x);
else if(i==sz)dfs2(v[x][i],k,x);
else{
int y=i+;
if(cir[v[x][y]]&&!cut&&v[x][y]>k&&cir[fa])dfs2(v[x][i],k,x);
else dfs2(v[x][i],v[x][y],x);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y;i<=m;i++)v[x=read()].push_back(y=read()),v[y].push_back(x);
for(int i=;i<=n;i++)sort(v[i].begin(),v[i].end());
if(m==n-)
{
dfs(,);
for(int i=;i<=n;i++)printf("%d ",a[i]);
}
else{
getcir(,);
for(int i=;i<=cnt;i++)cir[g[i]]=;
top=;
memset(vis,,sizeof vis);
dfs2(,n+,);
for(int i=;i<=n;i++)printf("%d ",a[i]);
}
}
斯坦纳树:https://www.luogu.org/problemnew/show/P3264
#include<bits/stdc++.h>
using namespace std;
const int N=;
struct edge{int v,nxt,w;}e[N<<];
int n,m,p,tot,hd[N],col[],f[<<][N/],cnt[],dp[<<];
bool vis[N],b[<<];
queue<int>q;
void add(int x,int y,int w){e[++tot]=(edge){y,hd[x],w},hd[x]=tot;}
void spfa(int S)
{
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=;
for(int i=hd[u];i;i=e[i].nxt)
if(f[S][e[i].v]>f[S][u]+e[i].w)
{
f[S][e[i].v]=f[S][u]+e[i].w;
if(!vis[e[i].v])q.push(e[i].v),vis[e[i].v]=;
}
}
}
bool check(int S)
{
int c=,ret=;
for(int i=;i<p;i++)
if(S&(<<i))
{
if(c&&col[i]!=c)return ;
c=col[i],ret++;
}
return ret==cnt[c];
}
int main()
{
memset(f,0x3f,sizeof f);
scanf("%d%d%d",&n,&m,&p);
for(int i=,x,y,z;i<=m;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
for(int i=,x;i<p;i++)scanf("%d%d",&col[i],&x),cnt[col[i]]++,f[<<i][x]=;
while(!q.empty())q.pop();
for(int S=;S<(<<p);S++)
{
for(int T=(S-)&S;T;T=(T-)&S)for(int i=;i<=n;i++)
f[S][i]=min(f[S][i],f[T][i]+f[S^T][i]);
for(int i=;i<=n;i++)if(f[S][i]<1e9)q.push(i),vis[i]=;
spfa(S);
}
for(int S=;S<(<<p);S++)
{
dp[S]=1e9;
for(int i=;i<=n;i++)dp[S]=min(dp[S],f[S][i]);
}
for(int S=;S<(<<p);S++)b[S]=check(S);
for(int S=;S<(<<p);S++)
for(int T=(S-)&S;T;T=(T-)&S)
if(b[T]&&b[S^T])b[S]=,dp[S]=min(dp[S],dp[T]+dp[S^T]);
printf("%d",dp[(<<p)-]);
}
虚树:https://www.luogu.org/problemnew/show/P3233
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+;
int n,m,Q,cnt,top,fa[N][],dep[N],sz[N],dfn[N],a[N],b[N],c[N],s[N],bel[N],rem[N],f[N];
vector<int>G[N];
bool cmp(int a,int b){return dfn[a]<dfn[b];}
void dfs(int u)
{
dfn[u]=++cnt,sz[u]=;
for(int i=;i<G[u].size();i++)
if(G[u][i]!=fa[u][])
fa[G[u][i]][]=u,dep[G[u][i]]=dep[u]+,dfs(G[u][i]),sz[u]+=sz[G[u][i]];
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int t=dep[x]-dep[y];
for(int i=;(<<i)<=t;i++)if(t&(<<i))x=fa[x][i];
if(x==y)return x;
for(int i=;~i;i--)
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
int dis(int a,int b){return dep[a]+dep[b]-*dep[lca(a,b)];}
void dfs1(int u)
{
c[++cnt]=u,rem[u]=sz[u];
for(int i=;i<G[u].size();i++)
{
dfs1(G[u][i]);
if(!bel[G[u][i]])continue;
int t1=dis(bel[G[u][i]],u),t2=dis(bel[u],u);
if(t1==t2&&bel[G[u][i]]<bel[u]||t1<t2||!bel[u])bel[u]=bel[G[u][i]];
}
}
void dfs2(int u)
{
for(int i=;i<G[u].size();i++)
{
int t1=dis(bel[u],G[u][i]),t2=dis(bel[G[u][i]],G[u][i]);
if(t1==t2&&bel[G[u][i]]>bel[u]||t1<t2||!bel[G[u][i]])bel[G[u][i]]=bel[u];
dfs2(G[u][i]);
}
}
void solve(int a,int b)
{
int x=b,mid=b;
for(int i=;i>=;i--)if(dep[fa[x][i]]>dep[a])x=fa[x][i];
rem[a]-=sz[x];
if(bel[a]==bel[b]){f[bel[a]]+=sz[x]-sz[b];return;}
for(int i=;~i;i--)
{
int nxt=fa[mid][i];
if(dep[nxt]<=dep[a])continue;
int t1=dis(bel[a],nxt),t2=dis(bel[b],nxt);
if(t1>t2||t1==t2&&bel[b]<bel[a])mid=nxt;
}
f[bel[a]]+=sz[x]-sz[mid];
f[bel[b]]+=sz[mid]-sz[b];
}
int main()
{
scanf("%d",&n);
for(int i=,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
dfs();
for(int j=;j<=;j++)for(int i=;i<=n;i++)fa[i][j]=fa[fa[i][j-]][j-];
for(int i=;i<=n;i++)G[i].clear();
scanf("%d",&Q);
while(Q--)
{
top=cnt=;
scanf("%d",&m);
for(int i=;i<=m;i++)scanf("%d",&a[i]),b[i]=a[i];
for(int i=;i<=m;i++)bel[a[i]]=a[i];
sort(a+,a+m+,cmp);
if(bel[]!=)s[++top]=;
for(int i=;i<=m;i++)
{
int t=a[i],f=;
while(top>)
{
f=lca(s[top],t);
if(top>&&dep[f]<dep[s[top-]])G[s[top-]].push_back(s[top]),top--;
else if(dep[f]<dep[s[top]]){G[f].push_back(s[top--]);break;}
else break;
}
if(s[top]!=f)s[++top]=f;
s[++top]=t;
}
while(top>)G[s[top-]].push_back(s[top]),top--;
dfs1(),dfs2();
for(int i=;i<=cnt;i++)
for(int j=;j<G[c[i]].size();j++)
solve(c[i],G[c[i]][j]);
for(int i=;i<=cnt;i++)f[bel[c[i]]]+=rem[c[i]];
for(int i=;i<=m;i++)printf("%d ",f[b[i]]);puts("");
for(int i=;i<=cnt;i++)f[c[i]]=bel[c[i]]=rem[c[i]]=,G[c[i]].clear();
}
}
2-SAT:https://www.luogu.org/problemnew/show/P3825
#include<bits/stdc++.h>
#define mem(x) memset(x,0,sizeof x)
using namespace std;
const int N=2e5+;
int n,m,d,scc,cnt,top,c[N],s1[N],t1[N],dfn[N],low[N],part[N],hd[N],v[N],nxt[N],q[N];
char s[N],s2[N],t2[N],t[N];
bool vis[N],flag;
void add(int x,int y){v[++cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt;}
int opp(int x){return x>n?x-n:x+n;}
int jisuan(int x,char ch)
{
if(s[x]=='a')return ch=='B'?x:x+n;
if(s[x]=='b'||s[x]=='c')return ch=='A'?x:x+n;
if(ch=='C')return x+n;
return x;
}
void tarjan(int u)
{
dfn[u]=low[u]=++cnt;
q[++top]=u;
vis[u]=;
for(int i=hd[u];i;i=nxt[i])
if(!dfn[v[i]])
{
tarjan(v[i]);
low[u]=min(low[u],low[v[i]]);
}
else if(vis[v[i]])low[u]=min(low[u],dfn[v[i]]);
if(dfn[u]==low[u])
{
part[u]=++scc;
vis[u]=;
int now;
do{
now=q[top--];
vis[now]=;
part[now]=scc;
}while(now!=u);
}
}
void solve()
{
scc=cnt=;
mem(dfn);mem(low);mem(part);mem(hd);mem(nxt);
for(int i=;i<=m;i++)
if(s[s1[i]]!='x'&&s[t1[i]]!='x'&&s[s1[i]]-!=s2[i])
{
int u=jisuan(s1[i],s2[i]),v;
if(s[t1[i]]-==t2[i])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
else{
char S=s[s1[i]],T=s[t1[i]];
int x=c[s1[i]],y=c[t1[i]];
if(S=='x'&&T=='x'&&s2[i]!=t[x])
{
int u=jisuan(s1[i],s2[i]),v;
if(t2[i]==t[y])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
else if(S=='x'&&T!='x'&&s2[i]!=t[x])
{
int u=jisuan(s1[i],s2[i]),v;
if(s[t1[i]]-==t2[i])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
else if(S!='x'&&T=='x'&&s[s1[i]]-!=s2[i])
{
int u=jisuan(s1[i],s2[i]),v;
if(t2[i]==t[y])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
}
cnt=;
for(int i=;i<=n*;i++)if(!dfn[i])tarjan(i);
for(int i=;i<=n;i++)if(part[i]==part[i+n])return;
for(int i=;i<=n;i++)
if(part[i]<part[i+n])
{
if(s[i]=='a')printf("B");
else if(s[i]=='b'||s[i]=='c')printf("A");
else if(t[c[i]]=='A')printf("B");
else printf("A");
}
else{
if(s[i]=='a'||s[i]=='b')printf("C");
else if(s[i]=='c')printf("B");
else if(t[c[i]]=='A')printf("C");
else printf("B");
}
flag=;
}
void fact(int k)
{
if(flag)return;
if(k>d){solve();return;}
t[k]='A';fact(k+);t[k]='B';fact(k+);
}
int main()
{
scanf("%d%d",&n,&d);
d=;
scanf("%s",s+);
for(int i=;i<=n;i++)if(s[i]=='x')c[i]=++d;
scanf("%d",&m);
for(int i=;i<=m;i++)scanf("%d %c%d %c",&s1[i],&s2[i],&t1[i],&t2[i]);
fact();
if(!flag)puts("-1");
}
朱刘算法:http://acm.hdu.edu.cn/showproblem.php?pid=2121
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=;
struct edge{int u,v;ll w;}e[N*N];
int n,m,id[N],vis[N],pre[N],pos;
ll in[N];
ll zhuliu(int root,int V)
{
ll ret=;
while()
{
for(int i=;i<V;i++)in[i]=1e16;
memset(pre,-,sizeof pre);
for(int i=;i<n+m;i++)
if(e[i].u!=e[i].v&&in[e[i].v]>e[i].w)
{
in[e[i].v]=e[i].w;
pre[e[i].v]=e[i].u;
if(e[i].u==root)pos=i;
}
for(int i=;i<V;i++)
if(in[i]==1e16&&i!=root)return -;
int cnt=;
memset(id,-,sizeof id);
memset(vis,-,sizeof vis);
in[root]=;
for(int i=;i<V;i++)
{
ret+=in[i];
int u=i;
while(vis[u]!=i&&id[u]==-&&u!=root)vis[u]=i,u=pre[u];
if(u!=root&&id[u]==-)
{
for(int v=pre[u];u!=v;v=pre[v])id[v]=cnt;
id[u]=cnt++;
}
}
if(!cnt)break;
for(int i=;i<V;i++)
if(id[i]==-)id[i]=cnt++;
for(int i=;i<n+m;i++)
{
int u=e[i].u,v=e[i].v;
e[i].u=id[u];
e[i].v=id[v];
if(id[u]!=id[v])e[i].w-=in[v];
}
V=cnt;
root=id[root];
}
return ret;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
ll sum=;
for(int i=;i<m;i++)scanf("%d%d%lld",&e[i].u,&e[i].v,&e[i].w),e[i].u++,e[i].v++,sum+=e[i].w;
sum++;
for(int i=m;i<n+m;i++)e[i]=(edge){,i-m+,sum};
ll ret=zhuliu(,n+);
if(ret==-||ret>=*sum)puts("impossible\n");
else printf("%lld %d\n\n",ret-sum,pos-m);
}
}
仙人掌:https://www.lydsy.com/JudgeOnline/problem.php?id=1023
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+,M=N*;
int n,cnt,cnt2,tot,scc,ans,hd[N],v[M],nxt[M],deep[N],dfn[N],fa[N],on[N],fst[N],se[N];
int a[N*],q1[N],q2[N],hd2[N],v2[M],nxt2[M];
void add(int x,int y){v[++cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt;}
void add2(int x,int y){v2[++cnt2]=y;nxt2[cnt2]=hd2[x];hd2[x]=cnt2;}
void tarjan(int u,int f)
{
dfn[u]=++tot;deep[u]=deep[f]+;
for(int i=hd[u];i;i=nxt[i])
if(v[i]!=f)
{
if(!dfn[v[i]])
{
fa[v[i]]=u;
on[u]=;
tarjan(v[i],u);
if(!on[u])add2(u,v[i]),add(v[i],u);
}
else if(dfn[v[i]]<dfn[u])
{
scc++;
for(int j=u;j!=fa[v[i]];j=fa[j])
add2(n+scc,j),add2(j,n+scc),on[j]=;
}
}
}
void Max(int x,int v){if(v>=fst[x])se[x]=fst[x],fst[x]=v;else if(v>se[x])se[x]=v;}
void dfs2(int u,int f)
{
for(int i=hd2[u];i;i=nxt2[i])
if(v2[i]!=f)
{
if(v2[i]<=n)dfs2(v2[i],u),Max(u,fst[v2[i]]+);
else{//dfs每棵子仙人掌,然后做一次单调队列优化dp,同时更新环上最高点的f值
int len=,pos=;
for(int j=hd2[v2[i]];j;j=nxt2[j])
if(v2[j]!=u)dfs2(v2[j],v2[i]);
for(int j=hd2[v2[i]];j;j=nxt2[j])a[++len]=v2[j];
int lim=len/;
for(int j=;j<=len;j++)a[len+j]=a[j];//复制队列,保证每个点都更新到
int l=,r=,num=-1e9;
q1[l]=fst[a[]];q2[l]=;
for(int j=;j<=len*;j++)
if(a[j]!=u)
{
while(l<=r&&j-q2[l]>lim)l++;
if(l<=r)ans=max(ans,q1[l]+fst[a[j]]+j-q2[l]);
while(l<=r&&q1[r]+j-q2[r]<=fst[a[j]])r--;
q1[++r]=fst[a[j]];q2[r]=j;
}
for(int i=;i<=len;i++)
num=max(num,fst[a[i]]+min(deep[a[i]]-deep[u],len-deep[a[i]]+deep[u]));//一定不能写成len*2!!!
Max(u,num);
}
}
ans=max(ans,fst[u]+se[u]);
}
int main()
{
int T;scanf("%d%d",&n,&T);
while(T--)
{
int x,y,lst;
scanf("%d%d",&y,&lst);
while(--y)scanf("%d",&x),add(lst,x),add(x,lst),lst=x;
}
tarjan(,);//tarjan缩点双
dfs2(,);
printf("%d",ans);
}
A*搜索(k短路):https://www.luogu.org/problemnew/show/P2483
#include<bits/stdc++.h>
using namespace std;
const int N=,M=4e5+;
struct node{int u;double g,f;};
bool operator<(node a,node b){return a.f>b.f;}
struct edge{int v,nxt;double w;}e1[M],e2[M];
int n,m,cnt1,cnt2,ans,h1[M],h2[M],vis[N];
double val,d[N];
void add(int x,int y,double z)
{
e1[++cnt1]=(edge){y,h1[x],z},h1[x]=cnt1;
e2[++cnt2]=(edge){x,h2[y],z},h2[y]=cnt2;
}
void spfa()
{
for(int i=;i<=n;i++)d[i]=2e9;
queue<int>q;
q.push(),d[]=,vis[]=;
while(!q.empty())
{
int u=q.front();q.pop(),vis[u]=;
for(int i=h1[u];i;i=e1[i].nxt)
if(d[e1[i].v]>d[u]+e1[i].w)
{
d[e1[i].v]=d[u]+e1[i].w;
if(!vis[e1[i].v])vis[e1[i].v]=,q.push(e1[i].v);
}
}
}
void Astar()
{
if(d[n]==2e9)return;
priority_queue<node>q;
q.push((node){n,,d[n]});
while(!q.empty())
{
node u=q.top();q.pop();
if(u.u==){val-=u.g;if(val>=)ans++;else return;}
for(int i=h2[u.u];i;i=e2[i].nxt)
q.push((node){e2[i].v,u.g+e2[i].w,u.g+e2[i].w+d[e2[i].v]});
}
}
int main()
{
scanf("%d%d%lf",&n,&m,&val);
if(val==){printf("");return ;}
double z;
for(int i=,x,y;i<=m;i++)scanf("%d%d%lf",&x,&y,&z),add(x,y,z);
spfa(),Astar();
printf("%d",ans);
}
树上问题&图论模板整理的更多相关文章
- ACM算法模板整理
史诗级ACM模板整理 基本语法 字符串函数 istream& getline (char* s, streamsize n ); istream& getline (char* s, ...
- 字符串系列——KMP模板整理
KMP模板整理 KMP与扩展KMP: /*vs 2017/ vs code以外编译器,去掉windows.h头文件和system("pause");*/ #include<i ...
- 【学习笔记】OI模板整理
CSP2019前夕整理一下模板,顺便供之后使用 0. 非算法内容 0.1. 读入优化 描述: 使用getchar()实现的读入优化. 代码: inline int read() { int x=0; ...
- NOIP模板整理计划
先占个坑 [update]noip结束了,弃了 一.图论 1.单源最短路 洛谷P3371 (1)spfa 已加SLF优化 #include <iostream> #include < ...
- SDOI2019 省选前模板整理
目录 计算几何✔ DP 斜率优化✔ 四边形不等式✔ 轮廓线DP✘ 各种分治 CDQ分治✔ 点分治✔ 整体二分✔ 数据结构 线段树合并✔ 分块✔ K-D Tree LCT 可持久化Trie✔ Splay ...
- [OI]省选前模板整理
省选前把板子整理一遍,如果发现有脑抽写错的情况,欢迎各位神犇打脸 :) 数学知识 数论: //组合数 //C(n,m) 在n个数中选m个的方案数 ll C[N][N]; void get_C(int ...
- 『嗨威说』常见的C++函数模板整理(一)
开学两天,身上的职责直接变为两个班班长,三个小组组长,哇这事情估计够我忙活了,想躲都躲不掉啊,看来我还是真招人推荐各种管理职务啊,以后要是有人推荐我当经理啊领导啊该多好哈哈哈哈.记得今天奶奶生日,很开 ...
- STL模板整理 Binary search(二分查找)
前言: 之前做题二分都是手动二分造轮子,用起来总是差强人意,后来看到STL才发现前辈们早就把轮子造好了,不得不说比自己手动实现好多了. 常用操作 1.头文件 #include <algorith ...
- STL模板整理 全排列
概念: 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列.当m=n时所有的排列情况叫全排列.如果这组数有n个,那么全排列数为n!个. 比如a, ...
随机推荐
- 关于安装openfiler
简介 Openfiler 由rPath Linux驱动,它是一个基于浏览器的免费网络存储管理实用程序,可以在单一框架中提供基于文件的网络连接存储 (NAS) 和基于块的存储区域网 (SAN).Open ...
- Loadrunner11的关联问题 《转载》
Loadrunner11的关联问题 链接:http://www.51testing.com/html/15/523415-821644.html
- 爬虫(十七):Scrapy框架(四) 对接selenium爬取京东商品数据
1. Scrapy对接Selenium Scrapy抓取页面的方式和requests库类似,都是直接模拟HTTP请求,而Scrapy也不能抓取JavaScript动态谊染的页面.在前面的博客中抓取Ja ...
- mybatis xml <if>判断字符串相等
mybatis 映射文件中,if标签判断字符串相等,两种方式: 因为mybatis映射文件,是使用的ognl表达式,所以在判断字符串sex变量是否是字符串Y的时候, <if test=" ...
- (四)requests模块的cookies和代理操作
基于requests模块的cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取某个人“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不到 ...
- js模式-观察者模式
// 主题,接收状态变化,触发每个观察者 class Subject { constructor() { this.state = 0 this.observers = [] } getState() ...
- 2019-9-16 java上课知识整理总结(动手动脑,课后实验)
java上课知识整理总结(动手动脑,课后实验) 一,课堂测试 1,题目:课堂测试:像二柱子那样,花二十分钟写一个能自动生成30道小学四则运算题目的 “软件” 要求:(1)题目避免重复: (2)可定制( ...
- 外部 Storage Provider【转】
如果 Kubernetes 部署在诸如 AWS.GCE.Azure 等公有云上,可以直接使用云硬盘作为 Volume,下面是 AWS Elastic Block Store 的例子: 要在 Pod 中 ...
- Day3-T3
原题目 Describe:又是这种最大子矩阵捆绑一堆条件的题 code: #pragma GCC optimize(2) #include<bits/stdc++.h> #define j ...
- ntp时间同步服务器
[root@localhost ~]# ntpdate time.nist.gov 虚拟机时间不对 自动同步 sudo ntpdate asia.pool.ntp.org 要是同步后时间还是不 ...