• 题解-CF1239D Catowice City


    CF1239D Catowice City

    (n) 个人和 (n) 只猫。有 (m) 对人猫友谊,即第 (u_i) 个人认识第 (v_i) 只猫,保证第 (i) 个人和第 (i) 只猫认识。求 (j) 个人和 (p) 只猫使 (j+p=n(1le j,p<n)),并且这些人和猫互不认识。(t) 组测试数据。

    数据范围: (1le nle mle 10^6)(1le sum n,sum mle 10^6)


    首先这是个二分图,人一块,猫一块。

    将第 (i) 个人和第 (i) 只猫合并成一点,因为他们不能都选。

    (u_i)(v_i) 连一条有向边,表示如果第 (u_i) 点选人,(v_i) 点也必须选人

    如果出现环,则这些点要么全选人要么全选猫,不妨令选人。

    所以 ( exttt{Tarjan})强联通分量分出来。

    如果只有一个强联通分量,则必须全选人,与 ((1le j,p<n)) 不符,输出 ( exttt{No})

    否则选出拓扑序最后的强联通分量全选人,其他全选猫

    ( exttt{Tarjan}) 有个性质:编号为 (1) 的强联通分量拓扑序最后。

    时间复杂度 (Theta(n+m)),空间复杂度 (Theta(n+m))


    • 代码:
    #include <bits/stdc++.h>
    using namespace std;
    
    //Start
    typedef long long ll;
    typedef double db;
    #define mp(a,b) make_pair(a,b)
    #define x(a) a.first
    #define y(a) a.second
    #define b(a) a.begin()
    #define e(a) a.end()
    #define sz(a) int((a).size())
    #define pb(a) push_back(a)
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    
    //Data
    const int N=1e6;
    int n,m;
    vector<int> e[N+7];
    
    //Tarjan
    int ic,in[N+7],low[N+7],dfn[N+7],sc,st[N+7],cc,co[N+7],sm[N+7];
    void Tarjan(int u){
    	low[u]=dfn[u]=++ic,in[u]=1,st[++sc]=u;
    	for(int v:e[u])
    		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
    		else if(in[v]) low[u]=min(low[u],dfn[v]);
    	if(dfn[u]==low[u]) for(int v=0,t=++cc;v!=u;) v=st[sc--],co[v]=t,in[v]=0,sm[t]++;
    }
    
    //KonnyWen
    void KonnyWen(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) e[i].clear();
    	for(int i=1;i<=m;i++){
    		int u,v; scanf("%d%d",&u,&v);
    		if(u!=v) e[u].pb(v);
    	}
    	fill(dfn+1,dfn+n+1,0),fill(sm+1,sm+n+1,0),ic=sc=cc=0;
    	for(int i=1;i<=n;i++)if(!dfn[i]) Tarjan(i);
    	if(cc==1) return void(puts("No"));
    	printf("Yes
    %d %d
    ",sm[1],n-sm[1]);
    	for(int i=1;i<=n;i++)if(co[i]==1) printf("%d ",i); puts("");
    	for(int i=1;i<=n;i++)if(co[i]!=1) printf("%d ",i); puts("");
    }
    
    //Main
    int main(){
    	int t; scanf("%d",&t);
    	for(int ti=1;ti<=t;ti++) KonnyWen();
    	return 0;
    }
    

    祝大家学习愉快!

  • 相关阅读:
    Kooboo CMS
    Kooboo CMS
    Kooboo CMS
    Kooboo CMS
    Kooboo CMS
    Ajax.BeginForm VS Html.BeginForm
    ASP.NET或者 js方式实现文件夹多图片浏览的方式
    C++入门知识总结(1)
    几个步骤轻松搞定ASP.NET 依赖注入。
    使用GIT@OSChina 实现协同工作的方法。
  • 原文地址:https://www.cnblogs.com/Wendigo/p/12916838.html
Copyright © 2020-2023  润新知