• 最大半联通子图


    RT,调了一年

    思路大概两个月前就有所了解,一直口胡没写

    注意新图要去重边,一个很好的写法是把可以建的边按字典序排序,跟上一个比较

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    
    inline int max(int x,int y){return x>y?x:y;}
    
    inline int min(int x,int y){return x<y?x:y;}
    
    int n,m,MOD,cnt,Cnt,Ant,maxi,tarclock,colorclock,head[100005],
    	Head[100005],dfn[100005],low[100005],dep[100005],
    	size[100005],ind[100005],color[100005],f[100005],vis[100005];
    	
    std::queue<int> q;
    
    std::stack<int> s;
    
    struct edge{
    	int v,next;
    }e[1000005];
    
    inline void add(int u,int v){
    	e[++cnt].v=v;
    	e[cnt].next=head[u];
    	head[u]=cnt;
    }
    
    struct Edge{
    	int v,next;
    }E[1000005];
    
    inline void Add(int u,int v){
    	E[++Cnt].v=v;
    	E[Cnt].next=Head[u];
    	Head[u]=Cnt;
    }
    
    struct arr{
    	int u,v;
    }A[1000005];
    
    inline bool cmp(arr x,arr y){
    	if(x.u!=y.u)return x.u<y.u;
    	return x.v<y.v;
    }
    
    inline void tarjan(int u){
    	dfn[u]=low[u]=++tarclock;
    	vis[u]=1;
    	s.push(u);
    	for(int i=head[u];i!=-1;i=e[i].next){
    		int v=e[i].v;
    		if(!dfn[v]){
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		}
    		else if(vis[v])low[u]=min(low[u],dfn[v]);
    	}
    	if(low[u]==dfn[u]){
    		colorclock++;
    		while(1){
    			int x=s.top();
    			s.pop();
    			vis[x]=0;
    			color[x]=colorclock;
    			size[colorclock]++;
    	//		printf("%d in %d
    ",x,colorclock);
    			if(x==u)break;
    		}
    	}
    }
    
    inline void Rebuild(){
    	for(int u=1;u<=n;u++){
    		for(int i=head[u];i!=-1;i=e[i].next){
    			int v=e[i].v;
    			if(color[u]!=color[v]){
    				A[++Ant].u=color[u];
    				A[Ant].v=color[v];
    			}
    		}
    	}
    	std::sort(A+1,A+Ant+1,cmp);
    	for(int i=1;i<=Ant;i++){
    		if(A[i-1].u==A[i].u&&A[i-1].v==A[i].v)continue;
    		ind[A[i].v]++;
    		Add(A[i].u,A[i].v);
    	}
    //	for(int u=1;u<=n;u++){
    	//	printf("the ind of %d is %d
    ",u,ind[u]);
    //	}
    }
    
    inline void topo(){
    	for(int u=1;u<=colorclock;u++){
    		if(!ind[u]){
    			q.push(u);
    			f[u]=1;
    			dep[u]=size[u];
    		}
    	}
    	while(!q.empty()){
    		int u=q.front();
    		q.pop();
    		maxi=max(maxi,dep[u]);
    		for(int i=Head[u];i!=-1;i=E[i].next){
    			int v=E[i].v;
    			if(dep[v]<dep[u]+size[v]){
    		//		printf("%d is updated by %d
    ",v,u);
    				dep[v]=dep[u]+size[v];
    				f[v]=f[u]%MOD;
    			}
    			else if(dep[v]==dep[u]+size[v]){
    				f[v]=(f[v]+f[u])%MOD;
    			}
    			ind[v]--;
    			if(!ind[v]){
    				q.push(v);
    			}
    		}
    	}
    }
    
    inline void getans(){
    	int ans=0;
    	for(int i=1;i<=colorclock;i++){
    		if(dep[i]==maxi){
    			ans+=f[i];
    			ans%=MOD;
    		}
    	}
    //	for(int i=1;i<=colorclock;i++){
    //		printf("%d:dep=%d f=%d
    ",i,dep[i],f[i]);
    //	}
    	printf("%d
    %d
    ",maxi,ans);
    }
    
    int main(){
    	memset(head,-1,sizeof(head));
    	memset(Head,-1,sizeof(Head));
    	scanf("%d%d%d",&n,&m,&MOD);
    	for(int i=1;i<=m;i++){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		add(u,v);
    	}
    	for(int i=1;i<=n;i++){
    		if(!dfn[i])tarjan(i);
    	}
    	Rebuild();
    	topo();
    	getans();
    }
    
  • 相关阅读:
    在Kubernetes集群里安装微服务DevOps平台fabric8
    Kubernetes PV/PVC使用实践
    Kubernetes集群中Service的滚动更新
    jenkins权限管理,不同用户显示不同项目
    SSH连接与自动化部署工具paramiko与Fabric
    kubernetes 之ingress
    理解Docker(8):Docker 存储之卷(Volume)
    Rancher Server HA的高可用部署实验-学习笔记
    2015 年总结
    2015 年总结
  • 原文地址:https://www.cnblogs.com/Y15BeTa/p/11674093.html
Copyright © 2020-2023  润新知