去除过水的模板,包括但不限于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);
}

树上问题&图论模板整理的更多相关文章

  1. ACM算法模板整理

    史诗级ACM模板整理 基本语法 字符串函数 istream& getline (char* s, streamsize n ); istream& getline (char* s, ...

  2. 字符串系列——KMP模板整理

    KMP模板整理 KMP与扩展KMP: /*vs 2017/ vs code以外编译器,去掉windows.h头文件和system("pause");*/ #include<i ...

  3. 【学习笔记】OI模板整理

    CSP2019前夕整理一下模板,顺便供之后使用 0. 非算法内容 0.1. 读入优化 描述: 使用getchar()实现的读入优化. 代码: inline int read() { int x=0; ...

  4. NOIP模板整理计划

    先占个坑 [update]noip结束了,弃了 一.图论 1.单源最短路 洛谷P3371 (1)spfa 已加SLF优化 #include <iostream> #include < ...

  5. SDOI2019 省选前模板整理

    目录 计算几何✔ DP 斜率优化✔ 四边形不等式✔ 轮廓线DP✘ 各种分治 CDQ分治✔ 点分治✔ 整体二分✔ 数据结构 线段树合并✔ 分块✔ K-D Tree LCT 可持久化Trie✔ Splay ...

  6. [OI]省选前模板整理

    省选前把板子整理一遍,如果发现有脑抽写错的情况,欢迎各位神犇打脸 :) 数学知识 数论: //组合数 //C(n,m) 在n个数中选m个的方案数 ll C[N][N]; void get_C(int ...

  7. 『嗨威说』常见的C++函数模板整理(一)

    开学两天,身上的职责直接变为两个班班长,三个小组组长,哇这事情估计够我忙活了,想躲都躲不掉啊,看来我还是真招人推荐各种管理职务啊,以后要是有人推荐我当经理啊领导啊该多好哈哈哈哈.记得今天奶奶生日,很开 ...

  8. STL模板整理 Binary search(二分查找)

    前言: 之前做题二分都是手动二分造轮子,用起来总是差强人意,后来看到STL才发现前辈们早就把轮子造好了,不得不说比自己手动实现好多了. 常用操作 1.头文件 #include <algorith ...

  9. STL模板整理 全排列

    概念: 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列.当m=n时所有的排列情况叫全排列.如果这组数有n个,那么全排列数为n!个. 比如a, ...

随机推荐

  1. Kafka--windows下简单使用kafka命令

    参考 https://www.cnblogs.com/cici20166/p/9426417.html 启动zookeeper 只需要保证有可用的zookeeper,可以使用kafka内置的,也可以自 ...

  2. oracle数据泵导出导入

    先创建一个目录:比如 Create  or Replace directory  DATA_PUMP_DIR as 'D:\DataPipe';   然后给导入导出的用户赋权限: Grant read ...

  3. [题解] LuoguP6075 [JSOI2015]子集选取

    传送门 ps: 下面\(n\)和\(k\)好像和题目里的写反了...将就着看吧\(qwq\) 暴力打个表答案就出来了? 先写个结论,答案就是\(2^{nk}\). 为啥呢? 首先你需要知道,因为一个集 ...

  4. Docker 和虚拟机的区别

    版权所有,未经许可,禁止转载 章节 Docker 介绍 Docker 和虚拟机的区别 Docker 安装 Docker Hub Docker 镜像(image) Docker 容器(container ...

  5. ERROR in Cannot find module 'node-sass'

    windows下,通过淘宝的npm镜像安装 npm install node-sass --registry=https://registry.npm.taobao.org (之前安装好过,一段时间没 ...

  6. 【剑指Offer】面试题09. 用两个栈实现队列

    题目 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能.(若队列中没有元素,delete ...

  7. Java学生成绩系统

    package text; public class helloworld{ private String stunumber; private String name; private double ...

  8. JS ~ 返回上一步

      <a href=" javascript:window.history.back() "> 返回上一步 </a>

  9. [Mathematics][MIT 18.03] Detailed Explanation of the Frequency Problems in Second-Order Differential Equation of Oscillation System

    Well, to begin with, I'd like to say thank you to MIT open courses twice. It's their generosity that ...

  10. Cookie简单介绍

    Cookie 饼干. 其实是一份小数据, 是服务器给客户端,并且存储在客户端上的一份小数据 应用场景 自动登录.浏览记录.购物车. 为什么要有这个Cookie http的请求是无状态. 客户端与服务器 ...