zoukankan      html  css  js  c++  java
  • [NOI2008]假面舞会 (搜索+gcd)

    题意

    LuoguP1477

    题解

    对于每一条边(u,v)(u,v),建两条边(uv,1),(vu,1)(u o v,1),(v o u,-1)。跑bfsbfs,如果这个点已经来过,就把到当前的距离与已经得到的disdis值的差存起来,所有的值取一个gcdgcd就是最大的答案,最小的答案枚举一下3geq3的因数就行了。如果gcd<3gcd<3就无解。

    这是有环的情况,没有环的情况,最大的答案就是每个连通块的最长链长度加起来。最小答案是33。如果最长链的和<3<3就无解。

    CODE

    #pragma GCC optimize (3)
    #include <bits/stdc++.h>
    using namespace std;
    char cb[1<<15],*cs=cb,*ct=cb;
    #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
    void read(int &res){
    	char ch; for(;!isdigit(ch=getchar()););
    	for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0');
    }
    typedef long long LL;
    const int MAXN = 100005;
    const int MAXM = 1000005;
    int n, stk[MAXN], indx, m; bool vis[MAXN];
    int fir[MAXN], to[MAXM<<1], nxt[MAXM<<1], wt[MAXM<<1], cnt;
    inline void link(int u, int v, int w) {
    	to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; wt[cnt] = w;
    }
    int q[MAXN], s, t, dis[MAXN];
    vector<int>vec;
    int tot;
    void bfs(int S) {
    	s = 0, t = 0; bool flg = 0;
    	vis[S] = 1; dis[S] = m; q[t++] = S;
    	int Mn = m, Mx = m;
    	while(s < t) {
    		int u = q[s++];
    		for(int i = fir[u], v; i; i = nxt[i])
    			if(!vis[v=to[i]]) {
    				vis[v] = 1;
    				dis[v] = dis[u] + wt[i];
    				Mn = min(Mn, dis[v]);
    				Mx = max(Mx, dis[v]);
    				q[t++] = v;
    			}
    			else {
    				if(dis[v] != dis[u] + wt[i])
    					flg = 1, vec.push_back(abs(dis[u]+wt[i]-dis[v]));
    			}
    	}
    	if(!flg) tot += Mx - Mn + 1;
    }
    int main () {
    	read(n), read(m);
    	for(int i = 1, u, v; i <= m; ++i) read(u), read(v), link(u, v, 1), link(v, u, -1);
    	for(int i = 1; i <= n; ++i) if(!vis[i]) bfs(i);
    	if(vec.size()) {
    		int gcd = 0;
    		for(int i = vec.size()-1; i >= 0; --i)
    			gcd = __gcd(gcd, vec[i]);
    		if(gcd <= 2) puts("-1 -1");
    		else {
    			int ans = gcd;
    			for(int i = 3; i <= gcd; ++i)
    				if(gcd % i == 0) { ans = i; break; }
    			printf("%d %d
    ", gcd, ans);
    		}
    	}
    	else {
    		if(tot <= 2) puts("-1 -1");
    		else printf("%d 3
    ", tot);
    	}
    }
    
  • 相关阅读:
    Android应用开发——系统自带样式Android:theme
    Android权限Uri.parse的详细资料
    Android中级教程之Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)!
    Android源码下载方法详解
    C#编程中的66个好习惯,你有多少个
    浏览时只显示指定文件类型
    如何在32位ubuntu11.10 下编译android 4.0.1源码和goldfish内核
    USACO2.3.1 The Longest Prefix 题解
    usaco1.1.3 Friday the Thirteenth 题解
    USACO 2.4.5 Fractions to Decimals 题解
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039205.html
Copyright © 2011-2022 走看看