拓扑排序找最大环最小环
Posted sjsjsj-minus-si
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拓扑排序找最大环最小环相关的知识,希望对你有一定的参考价值。
找最大环 P5145 漂浮的鸭子
题意很明确:求图中的最大环
今天新学到的一种方法——
拓扑排序求环
由于拓扑排序每次都是从入度为0的点开始,而环上的点的入度都不会为0,所以环上的点就不会参加排序,也就是说,经过拓扑排序后剩下的边和点构成的都是环。
这样我们就可以直接把每个环扫一遍记录最大环就结束了。
//2019/09/27
#include<bits/stdc++.h>
using namespace std;
template <typename T>inline void rd(T &x)x=0;char c=getchar();int f=0;while(!isdigit(c))f|=c=='-';c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48);c=getchar();x=f?-x:x;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)
const int N=1e5+10;
struct edge
int v,next,w;
e[N];
int head[N],edge_num;
inline void add(int u,int v,int w)e[++edge_num].v=v;e[edge_num].w=w;e[edge_num].next=head[u];head[u]=edge_num;
int n,ans;
int deg[N];
queue<int>q;
inline void topo_sort()
while(!q.empty())
int u=q.front();q.pop();
ee(i,u)
int v=e[i].v;
if(--deg[v]==0)
q.push(v);
inline void get_ring()
int res=0;
while(!q.empty())
int u=q.front();q.pop();
ee(i,u)
int v=e[i].v,w=e[i].w;
if(!deg[v])continue;
res+=w;
deg[v]--;
q.push(v);
ans=max(ans,res);
int main()
#ifdef WIN32
freopen("","r",stdin);
#endif
rd(n);
rep(i,1,n)
int v,w;rd(v),rd(w);
deg[v]++;
add(i,v,w);
rep(i,1,n)
if(!deg[i])
q.push(i);
topo_sort();
rep(i,1,n)
if(deg[i])
q.push(i);
get_ring();
printf("%d",ans);
return 0;
找最小环 noip2015 信息传递
由于
环上的点的数量==边的数量
,所以建图的时候给每条边连上权值为1的边权即可找到最小环。
//2019/09/27
#include<bits/stdc++.h>
using namespace std;
template <typename T>inline void rd(T &x)x=0;char c=getchar();int f=0;while(!isdigit(c))f|=c=='-';c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48);c=getchar();x=f?-x:x;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)
const int N=2e5+10;
struct edge
int v,next,w;
e[N];
int head[N],edge_num;
inline void add(int u,int v,int w)e[++edge_num].v=v;e[edge_num].w=w;e[edge_num].next=head[u];head[u]=edge_num;
int n,ans=INT_MAX;
int deg[N];
queue<int>q;
inline void topo_sort()
while(!q.empty())
int u=q.front();q.pop();
ee(i,u)
int v=e[i].v;
if(--deg[v]==0)
q.push(v);
inline void get_ring()
int res=0;
while(!q.empty())
int u=q.front();q.pop();
ee(i,u)
int v=e[i].v,w=e[i].w;
if(!deg[v])continue;
res+=w;
deg[v]--;
q.push(v);
ans=min(ans,res);
int main()
#ifdef WIN32
freopen("","r",stdin);
#endif
rd(n);
rep(i,1,n)
int v;rd(v);
deg[v]++;
add(i,v,1);
rep(i,1,n)
if(!deg[i])
q.push(i);
topo_sort();
rep(i,1,n)
if(deg[i])
q.push(i);
get_ring();
printf("%d",ans);
return 0;
以上是关于拓扑排序找最大环最小环的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 919D Substring (拓扑排序+树形dp)
图结构练习——推断给定图是否存在合法拓扑序列(拓扑排序推断环)