• 1239D. Catowice City(强连通分量缩点)


    每个人有一只猫

    请你确定x和y

    使得x+y=n,同时x个人不认识y只猫

    结论1:对于每组人和猫,必选其一

    首先,当我们选择一个人的时候,他自己养的猫和认识的猫一定不能选

    根据结论1就必须选择他认识的猫的主人,否则会导致人数不够

    由于认识关系是单向的,所以是一张有向图

    选择一个人之后必须选择它的所有出边

    结论2:一整个强连通分量必选

    那么先强连通分量缩点,然后形成一个DAG,在DAG上找一个出度为0的点作为x,剩下的作为y即可

     

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+100;
    int n,m,t;
    vector<int> g[maxn];
    int low[maxn],dfn[maxn],cnt,scc,pos[maxn];
    stack<int> st;
    void tj (int x) {
        low[x]=dfn[x]=++cnt;
        st.push(x);
        for (int y:g[x]) {
            if (!low[y])  {
                tj(y);
                low[x]=min(low[x],low[y]);
            }
            else if (!pos[y]) {
                low[x]=min(low[x],dfn[y]);
            } 
        }
        if (low[x]==dfn[x]) {
            scc++;
            while (1) {
                int u=st.top();
                st.pop();
                low[u]=low[x];
                pos[u]=scc;
                if (u==x) break;
            }
        }
    }
    int in[maxn],out[maxn];
    int x[maxn],y[maxn];
    int main () {
        scanf("%d",&t);
        while (t--) {
            scanf("%d%d",&n,&m);
            cnt=scc=0;
            while (st.size()) st.pop(); 
            for (int i=1;i<=n;i++) pos[i]=dfn[i]=low[i]=out[i]=0;
            for (int i=1;i<=n;i++) g[i].clear();
            for (int i=1;i<=m;i++) {
                scanf("%d%d",x+i,y+i);
                if (x[i]==y[i]) continue;
                g[x[i]].push_back(y[i]);
            }
            for (int i=1;i<=n;i++) if (!low[i]) tj(i);
            for (int i=1;i<=m;i++) if (pos[x[i]]!=pos[y[i]]) out[pos[x[i]]]++;
            if (scc==1) {
                printf("No
    ");
                continue;
            }
            for (int i=1;i<=scc;i++) {
                if (out[i]==0) {
                    int cnt=0;
                    for (int j=1;j<=n;j++) cnt+=(pos[j]==i);
                    printf("Yes
    %d %d
    ",cnt,n-cnt);
                    for (int j=1;j<=n;j++) if (pos[j]==i) printf("%d ",j);
                    printf("
    ");
                    for (int j=1;j<=n;j++) if (pos[j]!=i) printf("%d ",j);
                    printf("
    ");
                    break;
                } 
            }
        }
    } 
  • 相关阅读:
    第六章例6-5
    第六章例6-3
    第六章例6-2
    获取JVM默认编码以及获取其它JVM属性的方法(转)
    Java读取文本文件中文乱码问题
    highcharts highstock API js图形
    swing/swt可视化开发工具windowbuilder免费了
    swt 引入 js 问题
    swt 例子
    经验分享:开发SWT应用两点心得(转)
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14362106.html
Copyright © 2020-2023  润新知