zoukankan      html  css  js  c++  java
  • [NOI2008] 假面舞会

    考虑到有环的情况下最大值就是所有环长的最大公约数,最小值就是最小公约数。
    无环则是所有最长链的和,以及(3)
    无法得到答案的情况特殊判断。
    本题是在有向图里找环和最长链的一个经典做法。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define N 100005
    
    struct P{int to,v;P(int x = 0,int y = 0){to = x,v = y;v = 0;}};
    
    std::vector<P>QWQ[N];
    
    ll n,m;
    
    ll maxn,minn,ans,res;
    
    inline ll gcd(ll a,ll b){return (a == 0) ? b : gcd(b % a,a);}
    
    ll dis[N];
    bool vis[N];
    
    inline void dfs(int u,ll s){
    	if(vis[u]){
    		ans = gcd(ans,abs(s - dis[u]));
    		return ;
    	}
    	dis[u] = s;
    	vis[u] = 1;
    	maxn = std::max(maxn,dis[u]);
    	minn = std::min(minn,dis[u]);
    	for(int i = 0;i < QWQ[u].size();++i){
    		int v = QWQ[u][i].to;
    		dfs(v,dis[u] + QWQ[u][i].v);
    	}
    	
    }
    
    int main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i = 1;i <= m;++i){
    		ll x,y;
    		scanf("%lld%lld",&x,&y);
    		P a;
    		a.to = y,a.v = 1;
    		QWQ[x].push_back(a);
    		a.to = x,a.v = -1;
    		QWQ[y].push_back(a);
    	}
    	for(int i = 1;i <= n;++i)
    	if(!vis[i]){
    		maxn = -1e18,minn = 1e18;
    		dfs(i,1);
    		res = res + maxn - minn + 1;
    	}
    	if(ans){
    		if(ans < 3){
    			puts("-1 -1");
    			return 0;
    		}
    		for(int i = 3;i <= ans;++i)
    		if(ans % i == 0){
    			std::cout<<ans<<" "<<i<<std::endl;
    			return 0;
    		}
    	}
    	if(res < 3){
    		puts("-1 -1");
    		return 0;
    	}
    	std::cout<<res<<" "<<3<<std::endl;
    }
    
  • 相关阅读:
    Windows Internals学习笔记(八)IO系统
    FPGA相关术语(一)
    Bilinear Filter
    总线与接口
    GPIO相关知识
    .NET IL学习笔记(一)
    Windows Internals学习笔记(七)Image Loader
    Windows Internals学习笔记(五)Synchronization
    struts2官方 中文教程 系列五:处理表单
    struts2官方 中文教程 系列四:Action
  • 原文地址:https://www.cnblogs.com/dixiao/p/15151613.html
Copyright © 2011-2022 走看看