大体按照 数学 图论 dp 数据结构 这样的顺序
模板集 这个真的只有模板了………………
·spfa
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 100005 5 ll n,m,k,l,a,b,c,d[maxn],s,visit[maxn]; 6 struct edge{int from,to,val;}; 7 vector<int>g[maxn];vector<edge>edges; 8 void add_edge(int f,int t,int v){ 9 g[f].push_back(k);edges.push_back({f,t,v});k+=1; 10 }void spfa(int s){ 11 for(int i=1;i<=n;i++)d[i]=2147483647;queue<int>q;q.push(s); 12 visit[s]=1,d[s]=0; 13 while(!q.empty()){int u=q.front();q.pop();visit[u]=0; 14 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 15 if(d[e.to]>d[u]+e.val){d[e.to]=d[u]+e.val; 16 if(!visit[e.to])q.push(e.to),visit[e.to]=1; 17 } 18 } 19 } 20 } 21 int main(){ 22 cin>>n>>m>>s;for(int i=1;i<=m;i++)cin>>a>>b>>c,add_edge(a,b,c);spfa(s); 23 for(int i=1;i<=n;i++)cout<<d[i]<<" "; 24 }
判负圈和差分约束系统
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 100005 5 ll n,m,k=0,l,a,b,c,d[maxn],s,visit[maxn],inv[maxn]; 6 struct edge{int from,to,val;}; 7 vector<int>g[maxn];vector<edge>edges; 8 void add_edge(int f,int t,int v){ 9 g[f].push_back(k);edges.push_back({f,t,v});k+=1; 10 }bool spfa(int s){ 11 for(int i=1;i<maxn;i++)d[i]=2147483647;queue<int>q;q.push(s); 12 visit[s]=1,d[s]=0; 13 while(!q.empty()){int u=q.front();q.pop();visit[u]=0; 14 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 15 if(d[e.to]>d[u]+e.val){d[e.to]=d[u]+e.val; 16 if(inv[e.to]>n)return 1; 17 if(!visit[e.to])q.push(e.to),visit[e.to]=1,inv[e.to]++; 18 } 19 } 20 }return 0; 21 } 22 int main(){ 23 cin>>l;while(l--){ 24 cin>>n>>m;memset(visit,0,sizeof(visit));memset(inv,0,sizeof(inv)); 25 for(int i=1;i<=m;i++){cin>>a>>b>>c; 26 add_edge(a,b,c);if(c>=0)add_edge(b,a,c); 27 } 28 if(spfa(1))cout<<"YE5"<<endl;else cout<<"N0"<<endl; 29 edges.clear();k=0;for(int i=1;i<maxn;i++)g[i].clear(); 30 } 31 }
·dj
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 100005 5 6 ll n,m,k,l,a,b,c,d[maxn],s,visit[maxn]; 7 struct edge{int from,to,val;}; 8 vector<int>g[maxn];vector<edge>edges; 9 void add_edge(int f,int t,int v){ 10 g[f].push_back(k);edges.push_back({f,t,v});k+=1; 11 } 12 13 struct node{int u,d; 14 bool operator <(node b)const{ 15 return d>b.d; 16 } 17 }; 18 void dj(int s){ 19 for(int i=1;i<=n;i++)d[i]=2147483647;priority_queue<node>q;q.push({s,0}); 20 visit[s]=1,d[s]=0; 21 while(!q.empty()){int u=q.top().u;q.pop();visit[u]=0; 22 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 23 if(d[e.to]>d[u]+e.val){d[e.to]=d[u]+e.val; 24 if(!visit[e.to])q.push({e.to,d[e.to]}),visit[e.to]=1; 25 } 26 } 27 } 28 } 29 30 int main(){ 31 cin>>n>>m>>s; 32 for(int i=1;i<=m;i++)scanf("%lld%lld%lld",&a,&b,&c),add_edge(a,b,c); 33 dj(s);for(int i=1;i<=n;i++)printf("%lld ",d[i]); 34 return 0; 35 }
·网络流
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 100005 5 #define inf 2000000000 6 ll n,m,k=0,l,a,b,c,d[maxn],s,t,visit[maxn],p[maxn],cur[maxn]; 7 struct edge{int from,to,cap,flow;}; 8 vector<int>g[maxn];vector<edge>edges; 9 void add_edge(int f,int t,int v){g[f].push_back(k);edges.push_back({f,t,v,0});k+=1;g[t].push_back(k);edges.push_back({t,f,0,0});k+=1;} 10 bool bfs(){queue<int>q;q.push(s);visit[s]=1; 11 for(int i=1;i<=n;i++)d[i]=inf;d[s]=0; 12 while(!q.empty()){int u=q.front();q.pop();visit[u]=0; 13 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 14 if(e.cap>e.flow&&d[e.to]>d[u]+1){d[e.to]=d[u]+1; 15 if(!visit[e.to])q.push(e.to),visit[e.to]=1; 16 } 17 } 18 }return d[t]!=inf; 19 } 20 ll dfs(int x,int a){if(a==0||x==t)return a;ll f=0,flow=0; 21 for(ll &i=cur[x];i<g[x].size();i++){edge &e=edges[g[x][i]]; 22 if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))){ 23 flow+=f,e.flow+=f,edges[g[x][i]^1].flow-=f;a-=f; 24 } 25 }return flow; 26 } 27 ll mf(ll s,ll t){ll flow=0; 28 while(bfs()){memset(cur,0,sizeof(cur)); 29 flow+=dfs(s,inf); 30 }return flow; 31 } 32 int main(){cin>>n>>m>>s>>t; 33 for(int i=1;i<=m;i++)cin>>a>>b>>c,add_edge(a,b,c); 34 cout<<mf(s,t)<<endl;return 0; 35 }
·费用流
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 100005 5 #define inf 2000000000 6 ll n,m,k=0,l,aa,a[maxn],b,c,e,d[maxn],s,t,visit[maxn],p[maxn],cur[maxn],flow=0,cost=0; 7 struct edge{ll from,to,cap,flow,cost;}; 8 vector<int>g[maxn];vector<edge>edges; 9 void add_edge(int f,int t,int v,int c){g[f].push_back(k);edges.push_back({f,t,v,0,c});k+=1; 10 g[t].push_back(k);edges.push_back({t,f,0,0,-c});k+=1;} 11 ll bfs(){queue<int>q;q.push(s);visit[s]=1;a[s]=inf; 12 for(int i=1;i<=n;i++)d[i]=inf;d[s]=0; 13 while(!q.empty()){int u=q.front();q.pop();visit[u]=0; 14 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 15 if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){d[e.to]=d[u]+e.cost;p[e.to]=g[u][i]; 16 a[e.to]=min(a[u],e.cap-e.flow); 17 if(!visit[e.to])q.push(e.to),visit[e.to]=1; 18 } 19 } 20 } 21 if(d[t]==inf)return 0; 22 flow+=(long long)1*a[t]; 23 cost+=(long long)1*d[t]*a[t];int u=t; 24 while(u!=s){ 25 edges[p[u]].flow+=a[t];edges[p[u]^1].flow-=a[t]; 26 u=edges[p[u]].from; 27 } 28 return true; 29 } 30 int main(){cin>>n>>m>>s>>t; 31 for(int i=1;i<=m;i++)cin>>aa>>b>>c>>e,add_edge(aa,b,c,e); 32 while(bfs()); 33 cout<<flow<<" "<<cost<<endl; 34 return 0; 35 }
·kruscall
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 2000005 5 struct edge{int from,to,val;}e[maxn]; 6 bool cmp(edge a,edge b){return a.val<b.val;} 7 ll n,m,k,l,a,b,c,fa[maxn],val=0; 8 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 9 void join(int x,int y){fa[find(x)]=find(y);} 10 int main(){cin>>n>>m; 11 for(int i=1;i<=n;i++)fa[i]=i; 12 for(int i=1;i<=m;i++)cin>>e[i].from>>e[i].to>>e[i].val; 13 sort(e+1,e+m+1,cmp); 14 for(int i=1;i<=m;i++){ 15 if(find(e[i].from)==find(e[i].to))continue; 16 else join(e[i].from,e[i].to),val+=e[i].val; 17 }cout<<val<<endl; 18 return 0; 19 }
·倍增lca
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxn 500005 4 #define ll long long 5 int n,m,k,l,a,b,s,c,fa[maxn][25],depth[maxn],visit[maxn]; 6 struct edge{int from,to;};vector<int>g[maxn];vector<edge>edges; 7 void add_edge(int f,int t){g[f].push_back(k);g[t].push_back(k+1); 8 edges.push_back({f,t});edges.push_back({t,f});k+=2; 9 }void dfs(int u){visit[u]=1;fa[s][0]=s; 10 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 11 if(visit[e.to])continue;depth[e.to]=depth[u]+1;fa[e.to][0]=u;dfs(e.to); 12 } 13 }int lca(int a,int b){if(depth[a]<depth[b])swap(a,b); 14 for(int i=21;i>=0;i--)if(depth[fa[a][i]]>=depth[b])a=fa[a][i];if(a==b)return a; 15 for(int i=21;i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];return fa[a][0]; 16 } 17 int main(){cin>>n>>m>>s; 18 for(int i=1;i<n;i++)scanf("%d%d",&a,&b),add_edge(a,b); 19 dfs(s); 20 for(int j=1;j<=21;j++)for(int i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1]; 21 for(int i=1;i<=m;i++)scanf("%d%d",&a,&b),printf("%d\n",lca(a,b)); 22 }
·树剖
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxn 100005 4 #define lson (node<<1) 5 #define rson (lson|1) 6 int n,m,k=0,num=0,a,b,c,s[maxn],depth[maxn],top[maxn],val[maxn],fa[maxn],id[maxn],idx[maxn],sz[maxn],wson[maxn],visit[maxn]; 7 struct edge{int from,to;};vector<edge>edges;vector<int>g[maxn]; 8 void add_edge(int f,int t){g[f].push_back(k);g[t].push_back(k+1);k+=2;edges.push_back({f,t});edges.push_back({t,f});} 9 int treesum[maxn*4],treemax[maxn*4]; 10 inline int rd(){int res=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){res=res*10+(ch&15);ch=getchar();}return f*res; 13 }void pushdown(int node){treemax[node]=max(treemax[lson],treemax[rson]);treesum[node]=treesum[lson]+treesum[rson];} 14 void dfs1(int u){visit[u]=1;sz[u]=1; 15 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];if(visit[e.to])continue;depth[e.to]=depth[u]+1,fa[e.to]=u; 16 dfs1(e.to);sz[u]+=sz[e.to];if(sz[e.to]>sz[wson[u]])wson[u]=e.to;} 17 }void dfs2(int u){visit[u]=1,id[u]=++num,idx[num]=u; 18 if(wson[u]!=0)top[wson[u]]=top[u],dfs2(wson[u]); 19 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 20 if(visit[e.to]||wson[u]==e.to)continue;top[e.to]=e.to;dfs2(e.to);} 21 }void build(int node,int l,int r){if(l==r){treesum[node]=treemax[node]=val[idx[l]];return ;}int mid=(l+r)>>1; 22 build(lson,l,mid);build(rson,mid+1,r);pushdown(node); 23 }void add(int node,int l,int r,int x,int k){if(l==r){treemax[node]=treesum[node]=k;return ;}int mid=(l+r)>>1; 24 if(x<=mid)add(lson,l,mid,x,k);else if(x>=mid+1)add(rson,mid+1,r,x,k);pushdown(node); 25 }int querysum(int node,int l,int r,int x,int y){ 26 if(l==x&&r==y){return treesum[node];}int mid=(l+r)>>1; 27 if(y<=mid)return querysum(lson,l,mid,x,y);else if(x>=mid+1)return querysum(rson,mid+1,r,x,y); 28 else return querysum(lson,l,mid,x,mid)+querysum(rson,mid+1,r,mid+1,y); 29 }int querymax(int node,int l,int r,int x,int y){ 30 if(l==x&&r==y){return treemax[node];}int mid=(l+r)>>1; 31 if(y<=mid)return querymax(lson,l,mid,x,y);else if(x>=mid+1)return querymax(rson,mid+1,r,x,y); 32 else return max(querymax(lson,l,mid,x,mid),querymax(rson,mid+1,r,mid+1,y)); 33 } 34 int findmax(int u,int v){int ans=-2000000000; 35 while(top[u]!=top[v]){if(depth[top[u]]<depth[top[v]])swap(u,v); 36 ans=max(ans,querymax(1,1,n,id[top[u]],id[u]));u=fa[top[u]];} 37 if(depth[u]<depth[v])swap(u,v);ans=max(ans,querymax(1,1,n,id[v],id[u]));return ans; 38 }int findsum(int u,int v){int ans=0; 39 while(top[u]!=top[v]){if(depth[top[u]]<depth[top[v]])swap(u,v); 40 ans+=querysum(1,1,n,id[top[u]],id[u]);u=fa[top[u]]; 41 }if(depth[u]<depth[v])swap(u,v);ans+=querysum(1,1,n,id[v],id[u]);return ans; 42 } 43 int main(){n=rd();for(int i=1;i<n;i++)a=rd(),b=rd(),add_edge(a,b); 44 dfs1(1);memset(visit,0,sizeof(visit));dfs2(1); 45 for(register int i=1;i<=n;i++)val[i]=rd(); 46 m=rd();build(1,1,n); 47 for(register int i=1;i<=m;i++){string hh;cin>>hh; 48 if(hh=="QMAX")a=rd(),b=rd(),printf("%d\n",findmax(a,b)); 49 if(hh=="QSUM")a=rd(),b=rd(),printf("%d\n",findsum(a,b)); 50 if(hh=="CHANGE")a=rd(),b=rd(),add(1,1,n,id[a],b); 51 }return 0; 52 }
·lct
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=10010; 4 struct node{int fa,ch[2];bool reverse,is_root;}T[maxn]; 5 int n,m; 6 void pushreverse(int x){if(!x)return;swap(T[x].ch[0],T[x].ch[1]);T[x].reverse^=1;} 7 void pushdown(int x){ 8 if(T[x].reverse){ 9 pushreverse(T[x].ch[0]),pushreverse(T[x].ch[1]),T[x].reverse=false; 10 } 11 }int getson(int x){return x==T[T[x].fa].ch[1];} 12 void rotate(int x){if(T[x].is_root)return; 13 int k=getson(x),fa=T[x].fa; 14 int fafa=T[fa].fa; 15 T[fa].ch[k]=T[x].ch[k^1]; 16 if(T[x].ch[k^1])T[T[x].ch[k^1]].fa=fa; 17 T[x].ch[k^1]=fa,T[fa].fa=x,T[x].fa=fafa; 18 if(!T[fa].is_root)T[fafa].ch[fa==T[fafa].ch[1]]=x; 19 else T[x].is_root=true,T[fa].is_root=false; 20 }void push(int x){if(!T[x].is_root)push(T[x].fa);pushdown(x);} 21 void splay(int x){push(x); 22 for(int fa;!T[x].is_root;rotate(x)){ 23 if(!T[fa=T[x].fa].is_root){ 24 rotate((getson(x)==getson(fa))?fa:x); 25 } 26 } 27 }void access(int x){ 28 int y=0;do{ 29 splay(x);T[T[x].ch[1]].is_root=true; 30 T[T[x].ch[1]=y].is_root=false;x=T[y=x].fa; 31 }while(x); 32 }bool judge(int u,int v){ 33 while(T[u].fa)u=T[u].fa;while(T[v].fa)v=T[v].fa; 34 return u==v; 35 }void mroot(int x){access(x);splay(x);pushreverse(x);} 36 void link(int u,int v){mroot(u);T[u].fa=v;} 37 void cut(int u,int v){mroot(u);access(v);splay(v); 38 T[T[v].ch[0]].fa=T[v].fa; 39 T[T[v].ch[0]].is_root=true; 40 T[v].fa=0;T[v].ch[0]=0; 41 }void work(){ 42 char opt[50];int u,v; 43 while(m--){cin>>opt>>u>>v; 44 if(opt[0]=='Q'){ 45 if(judge(u,v))printf("Yes\n"); 46 else printf("No\n"); 47 }else if(opt[0]=='C')link(u,v);else if(opt[0]=='D')cut(u,v); 48 } 49 }int main(){cin>>n>>m; 50 for(int i=1;i<=n;i++){ 51 T[i].reverse=T[i].fa=T[i].ch[0]=T[i].ch[1]=0;T[i].is_root=true; 52 }work();return 0; 53 }
·无向图tarjan只割顶 桥
·流图tarjan
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 10005 5 int n,m,k,l,a,b,c,val[maxn],scc[maxn],cnt=0,num=0,dfn[maxn],low[maxn],ins[maxn],sz[maxn],in[maxn],out[maxn],d[maxn],mx=-1000000000; 6 struct edge{int from,to;};vector<edge>edges;vector<int>g[maxn];vector<edge>edges2;vector<int>mp[maxn]; 7 void add_edge(int f,int t){g[f].push_back(k++),edges.push_back({f,t});} 8 stack<int>s;queue<int>q; 9 void tarjan(int u){dfn[u]=low[u]=++num;s.push(u);ins[u]=1; 10 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 11 if(!dfn[e.to]){tarjan(e.to); 12 low[u]=min(low[u],low[e.to]); 13 }else if(ins[e.to]){ 14 low[u]=min(low[u],low[e.to]); 15 } 16 }if(dfn[u]==low[u]){cnt++;int now; 17 do{ now=s.top();s.pop();ins[now]=0; 18 scc[now]=cnt,sz[cnt]+=val[now]; 19 }while(now!=u); 20 } 21 } 22 int main(){ 23 cin>>n>>m;for(int i=1;i<=n;i++)cin>>val[i];for(int i=1;i<=m;i++)cin>>a>>b,add_edge(a,b); 24 for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i); 25 for(int i=0;i<edges.size();i++){edge &e=edges[i]; 26 if(scc[e.to]!=scc[e.from]) 27 mp[scc[e.from]].push_back(l++),edges2.push_back({scc[e.from],scc[e.to]}), 28 in[scc[e.to]]++,out[scc[e.from]]++; 29 } 30 for(int i=1;i<=cnt;i++)if(!in[i])q.push(i),d[i]=sz[i]; 31 while(!q.empty()){int u=q.front();q.pop(); 32 for(int i=0;i<mp[u].size();i++){ 33 edge &e=edges2[mp[u][i]]; 34 in[e.to]--;d[e.to]=max(d[e.to],d[u]+sz[e.to]); 35 if(in[e.to]==0){ 36 q.push(e.to); 37 } 38 } 39 }for(int i=1;i<=cnt;i++)mx=max(d[i],mx); 40 cout<<mx<<endl; 41 }
·2-sat
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define maxn 2000005 5 int n,m,k=0,l,a,b,c,d,num=0,root,cnt=0,ins[maxn],val[maxn],dfn[maxn],low[maxn],scc[maxn]; 6 struct edge{int from,to;}; 7 vector<edge>edges;vector<int>g[maxn];stack<int>s; 8 void tarjan(int u){ 9 s.push(u);ins[u]=1;dfn[u]=low[u]=++num; 10 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 11 if(!dfn[e.to]){tarjan(e.to); 12 low[u]=min(low[u],low[e.to]); 13 }else if(ins[e.to])low[u]=min(low[u],low[e.to]); 14 }if(dfn[u]==low[u]){int y;cnt++; 15 do{y=s.top();s.pop(); 16 scc[y]=cnt,ins[y]=0; 17 }while(u!=y); 18 } 19 } 20 int main(){scanf("%d%d",&n,&m); 21 for(register int i=1;i<=m;i++){ 22 scanf("%d%d%d%d",&a,&b,&c,&d); 23 edges.push_back({c+((1-d)*n),a+(b*n)}); 24 edges.push_back({a+((1-b)*n),c+(d*n)}); 25 g[c+((1-d)*n)].push_back(k); 26 g[a+((1-b)*n)].push_back(k+1);k+=2; 27 } 28 for(register int i=1;i<=2*n;i++)if(!dfn[i])tarjan(i); 29 for(register int i=1;i<=n;i++){ 30 if(scc[i]==scc[i+n]){printf("IMPOSSIBLE\n");return 0;} 31 else val[i]=scc[i]>scc[i+n]; 32 } 33 printf("POSSIBLE\n"); 34 for(register int i=1;i<=n;i++)printf("%d ",val[i]); 35 return 0; 36 }
·点分(这个考就没意思了………………)打的聪聪可可那个
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxn 20005 4 struct edge{int from,to,val;}; 5 vector<int>g[maxn];vector<edge>edges; 6 int n,m,k=0,a,b,c,d[maxn],root,done[maxn],sz[maxn],msz[maxn],tag[maxn],sum,visit[maxn],ans=0; 7 void add_edge(int f,int t,int v){g[f].push_back(k);edges.push_back({f,t,v%3});g[t].push_back(k+1);edges.push_back({t,f,v%3});k+=2;} 8 int gcd(int a,int b){return b==0?a:gcd(b,a%b);} 9 void dfs(int u){visit[u]=1;msz[u]=0; 10 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 11 if(visit[e.to]||done[e.to])continue; 12 dfs(e.to);sz[u]+=sz[e.to];msz[u]=max(sz[e.to],msz[u]); 13 }msz[u]=max(sum-sz[u],msz[u]); 14 if(msz[root]>msz[u]||root==0)root=u; 15 }void dfs2(int u){visit[u]=1;tag[d[u]]++; 16 for(int i=0;i<g[u].size();i++){ 17 edge &e=edges[g[u][i]];if(visit[e.to]||done[e.to])continue; 18 d[e.to]=d[u]+e.val;d[e.to]%=3;dfs2(e.to); 19 } 20 }int cal(int u,int v){tag[0]=tag[1]=tag[2]=0,d[u]=v,dfs2(u); 21 memset(visit,0,sizeof(visit));memset(d,0,sizeof(d)); 22 return tag[1]*tag[2]*2+tag[0]*tag[0]; 23 }void solve(int s){ans+=cal(s,0);done[s]=1; 24 for(int i=0;i<g[s].size();i++){edge &e=edges[g[s][i]]; 25 if(done[e.to])continue; 26 ans-=cal(e.to,e.val),root=0,sum=sz[e.to]; 27 for(int i=1;i<=n;i++)sz[i]=1; 28 memset(msz,0,sizeof(msz));dfs(e.to); 29 memset(visit,0,sizeof(visit));solve(root); 30 } 31 }int main(){cin>>n;sum=n;for(int i=1;i<=n;i++)sz[i]=1; 32 for(int i=1;i<n;i++)scanf("%d%d%d",&a,&b,&c),add_edge(a,b,c); 33 dfs(1),memset(visit,0,sizeof(visit)),solve(root); 34 int dd=gcd(ans,n*n);cout<<ans/dd<<"/"<<n*n/dd<<endl; 35 }
·拓扑排序和基环树
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mod 80112002 4 #define ll long long 5 #define maxn 100005 6 ll n,m,k,l,in[maxn],out[maxn],visit[maxn],a,b,f[maxn]; 7 struct edge{int from,to,val;}; 8 vector<int>g[maxn];vector<edge>edges; 9 void add_edge(int f,int t){g[f].push_back(k++);edges.push_back({f,t});in[b]++,out[a]++;} 10 void dfs(int u){visit[u]=1; 11 for(int i=0;i<g[u].size();i++){ 12 edge &e=edges[g[u][i]];f[e.to]+=f[u],f[e.to]%=mod;if(--in[e.to]==0)dfs(e.to); 13 } 14 } 15 int main(){cin>>n>>m;for(int i=1;i<=m;i++)cin>>a>>b,add_edge(a,b); 16 for(int i=1;i<=n;i++){ 17 if(!in[i]&&out[i]&&!visit[i])f[i]=1,dfs(i); 18 }for(int i=1;i<=n;i++){if(!out[i])l+=f[i],l%=mod;}cout<<l%mod<<endl; 19 return 0; 20 }
·缩点
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define maxn 10005 5 int n,m,k,l,a,b,c,val[maxn],scc[maxn],cnt=0,num=0,dfn[maxn],low[maxn],ins[maxn],sz[maxn],in[maxn],out[maxn],d[maxn],mx=-1000000000; 6 struct edge{int from,to;};vector<edge>edges;vector<int>g[maxn];vector<edge>edges2;vector<int>mp[maxn]; 7 void add_edge(int f,int t){g[f].push_back(k++),edges.push_back({f,t});} 8 stack<int>s;queue<int>q; 9 void tarjan(int u){dfn[u]=low[u]=++num;s.push(u);ins[u]=1; 10 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 11 if(!dfn[e.to]){tarjan(e.to); 12 low[u]=min(low[u],low[e.to]); 13 }else if(ins[e.to]){ 14 low[u]=min(low[u],low[e.to]); 15 } 16 }if(dfn[u]==low[u]){cnt++;int now; 17 do{ now=s.top();s.pop();ins[now]=0; 18 scc[now]=cnt,sz[cnt]+=val[now]; 19 }while(now!=u); 20 } 21 } 22 int main(){ 23 cin>>n>>m;for(int i=1;i<=n;i++)cin>>val[i];for(int i=1;i<=m;i++)cin>>a>>b,add_edge(a,b); 24 for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i); 25 for(int i=0;i<edges.size();i++){edge &e=edges[i]; 26 if(scc[e.to]!=scc[e.from]) 27 mp[scc[e.from]].push_back(l++),edges2.push_back({scc[e.from],scc[e.to]}), 28 in[scc[e.to]]++,out[scc[e.from]]++; 29 } 30 for(int i=1;i<=cnt;i++)if(!in[i])q.push(i),d[i]=sz[i]; 31 while(!q.empty()){int u=q.front();q.pop(); 32 for(int i=0;i<mp[u].size();i++){ 33 edge &e=edges2[mp[u][i]]; 34 in[e.to]--;d[e.to]=max(d[e.to],d[u]+sz[e.to]); 35 if(in[e.to]==0){ 36 q.push(e.to); 37 } 38 } 39 }for(int i=1;i<=cnt;i++)mx=max(d[i],mx); 40 cout<<mx<<endl; 41 }