• 拓扑排序找最大环最小环


    找最大环 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;
    }
    
  • 相关阅读:
    [C和指针]第一部分
    [Effective Java]第十章 并发
    [C程序设计语言]第五部分
    [C程序设计语言]第四部分
    git clone速度太慢解决方案
    Golang使用Redis
    删除校管理员的多余数据
    jQuery ajax同步的替换方法,使用 $.Deferred()对象
    打包并删除临时文件
    通过vjudge刷Uva的题目(解决Uva网站打开慢的问题)
  • 原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634669.html
Copyright © 2020-2023  润新知