zoukankan      html  css  js  c++  java
  • [TopCoder14647]HiddenRabbits

    vjudge

    description

    有一棵(n)个节点的树和(m)只兔子,每只兔子要住在一个点上(可以多只兔子住在同一个点上)。有(q)组要求,每组形如“当以(r)为根时,兔子(a)和兔子(b)居住的点的(mbox{LCA})要是(x)”。求一组合法方案,或判断不合法。
    (n,m,qle250)

    sol

    (mbox{2-sat})
    (S(i,j))表示(i)号兔子是否住在(j)节点的子树中。这里的子树是随便选一个点出来当作根的。
    一些比较显然的连边(以下连边默认加上逆否命题的连边):
    (lnot S(i,rt) o S(i,rt))
    (S(i,u) o S(i,fa_u))
    (S(i,u) o lnot S(i,v))当且仅当(u,v)不存在祖孙关系。
    然后就需要考虑每组要求了。
    这里由于换根,需要对子树特殊处理,方法比较像[BZOJ3083]遥远的国度
    (Case 1:x=r)
    那么(a)(b)就要在(x(r))的不同子树内,对于(x)的每一个儿子(u),若(a,b)其中一个在子树(u)内另外一个就不能在。注意到(x(r))可能不是树根(rt),所以(a,b)中的其中一个还可能在(x(r))的上方部分。
    (Case 2:r)(x)的子树中(这里是以选定的(rt)为根的子树)
    (r)(y)的子树中,其中(y in son(x))
    连边和上一种(Case)基本相同,除了(a,b)都不能在(y)这棵子树中。
    (Otherwise)
    (a,b)都必须要在(x)的子树中,且不能在相同儿子的子树中。
    建完边之后跑(Tarjan)就好了。
    点数是(O(n^2)),边数(O(n^3)),总复杂度(O(n^3))

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 505;
    const int M = 2e7+5;
    int n,m,q,fa[N],r[N],a[N],b[N],x[N],pre[N],ft[N],st[N],ed[N],tim,S[N][N],tot=-1;
    int to[M],nxt[M],head[N*N],cnt,dfn[N*N],low[N*N],s[N*N],vis[N*N],bel[N*N],scc;
    vector<int>ans;
    void dfs(int u){
    	st[u]=++tim;
    	for (int v=ft[u];v;v=pre[v]) dfs(v);
    	ed[u]=tim;
    }
    bool in(int x,int y){//whether x is in y's subtree
    	return st[x]>=st[y]&&st[x]<=ed[y];
    }
    void link(int u,int v){
    	to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
    	u^=1;v^=1;swap(u,v);
    	to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
    }
    void Tarjan(int u){
    	dfn[u]=low[u]=++tim;vis[s[++s[0]]=u]=1;
    	for (int e=head[u];e;e=nxt[e])
    		if (!dfn[to[e]]) Tarjan(to[e]),low[u]=min(low[u],low[to[e]]);
    		else if (vis[to[e]]) low[u]=min(low[u],dfn[to[e]]);
    	if (dfn[u]==low[u]){
    		++scc;int x;
    		do x=s[s[0]--],vis[x]=0,bel[x]=scc; while (x^u);
    	}
    }
    void work(){
    	for (int i=1;i<=n;++i) pre[i]=ft[fa[i]],ft[fa[i]]=i;
    	dfs(0);
    	for (int i=0;i<m;++i)
    		for (int j=0;j<=n;++j)
    			S[i][j]=++tot,++tot;
    	for (int i=0;i<m;++i){
    		link(S[i][0]^1,S[i][0]);
    		for (int u=1;u<=n;++u) link(S[i][u],S[i][fa[u]]);
    		for (int u=1;u<=n;++u)
    			for (int v=u+1;v<=n;++v)
    				if (!in(u,v)&&!in(v,u)) link(S[i][u],S[i][v]^1);
    	}
    	for (int i=0;i<q;++i){
    		if (x[i]==r[i]){
    			link(S[a[i]][x[i]]^1,S[b[i]][x[i]]);
    			for (int u=ft[x[i]];u;u=pre[u]) link(S[a[i]][u],S[b[i]][u]^1);
    		}
    		else if (in(r[i],x[i])){
    			int y=r[i];while (fa[y]!=x[i]) y=fa[y];
    			link(S[a[i]][y],S[a[i]][y]^1);
    			link(S[b[i]][y],S[b[i]][y]^1);
    			link(S[a[i]][x[i]]^1,S[b[i]][x[i]]);
    			for (int u=ft[x[i]];u;u=pre[u]) if (u!=y) link(S[a[i]][u],S[b[i]][u]^1);
    		}
    		else{
    			link(S[a[i]][x[i]]^1,S[a[i]][x[i]]);
    			link(S[b[i]][x[i]]^1,S[b[i]][x[i]]);
    			for (int u=ft[x[i]];u;u=pre[u]) link(S[a[i]][u],S[b[i]][u]^1);
    		}
    	}
    	for (int i=tim=0;i<=tot;++i) if (!dfn[i]) Tarjan(i);
    	for (int i=0;i<=tot;i+=2) if (bel[i]==bel[i^1]) return;
    	for (int i=0;i<m;++i){
    		int res=0;
    		for (int j=1;j<=n;++j)
    			if (bel[S[i][j]]<bel[S[i][j]^1]) res=j;
    		ans.push_back(res);
    	}
    	return;
    }
    class HiddenRabbits{
    public:
    	vector<int> whereAreTheRabbits(vector<int>ff,int mm,vector<int>rr,vector<int>aa,vector<int>bb,vector<int>xx){
    		n=ff.size();q=rr.size();m=mm;
    		for (int i=1;i<=n;++i) fa[i]=ff[i-1];
    		for (int i=0;i<q;++i) r[i]=rr[i],a[i]=aa[i],b[i]=bb[i],x[i]=xx[i];
    		work();return ans;
    	}
    };
    
  • 相关阅读:
    特征归一化
    什么是端到端(end2end)学习?
    RSA加密原理及其证明
    python脚本中__all__变量的用法
    洛谷 1108 低价购买
    洛谷 3029 [USACO11NOV]牛的阵容Cow Lineup
    洛谷 1365 WJMZBMR打osu! / Easy
    洛谷 2759 奇怪的函数
    洛谷 2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
    牛客网NOIP赛前集训营 提高组 第5场 T2 旅游
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9414820.html
Copyright © 2011-2022 走看看