找最大环 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; }