zoukankan      html  css  js  c++  java
  • P2746 [USACO5.3]校园网Network of Schools

    题目地址


    简述:

    • 缩点后进行条件判定.

    易错点:

    • 首先,可以进行缩点.
    • 子任务1:缩点后入度为零的强连通分量必须要有新软件.
    • 子任务2:要求加边后形成一个强连通图。可以考虑到缩点后的DAG上每个点都必须同时具有入度和出度,就可以将没有入度的点的数量记为p,没有出度的点的数量记为q;由于没有出度的点可以直接连接没有入度的点,答案即为max(p,q).

    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<cstring>
    using namespace std;
    const int MAXN=1000010,MAXM=1000010;
    struct firstEdge1{
        int from,to,nxt;
    }firstEdge[MAXM];
    int firstHead[MAXN],firstEdgeCnt=0;
    void addFirstEdge(int u,int v){
        firstEdge[++firstEdgeCnt].from=u;
        firstEdge[firstEdgeCnt].to=v;
        firstEdge[firstEdgeCnt].nxt=firstHead[u];
        firstHead[u]=firstEdgeCnt;
    }
    int dfn[MAXN],low[MAXN],dfnCnt=0;
    bool inc[MAXN];
    int stck[MAXN],c[MAXN],top=0;
    int sccCnt=0;
    vector<int> sccVec[MAXN];
    void tarjan(int x){
        low[x]=dfn[x]=++dfnCnt;
        inc[x]=1;
        stck[++top]=x;
        for(int i=firstHead[x];i;i=firstEdge[i].nxt){
            int v=firstEdge[i].to;
            if(!dfn[v]){ 
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }else if(inc[v])low[x]=min(low[x],dfn[v]);
        }
        if(dfn[x]==low[x]){
            int y;sccCnt++;
            do{
                y=stck[top--];
                inc[y]=0;
                c[y]=sccCnt;
                sccVec[sccCnt].push_back(y);
            }while(x!=y);
        }
    }
    struct SecondEdge{
        int from,to,nxt;
    }secondEdge[MAXM];
    int secondHead[MAXN],secondEdgeCnt=0;
    void addSecondEdge(int u,int v){
        secondEdge[++secondEdgeCnt].from=u;
        secondEdge[secondEdgeCnt].to=v;
        secondEdge[secondEdgeCnt].nxt=secondHead[secondEdgeCnt];
        secondHead[u]=secondEdgeCnt;
    }
    int rd[MAXN],cd[MAXN];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int tmp;
            while(true){
                scanf("%d",&tmp);
                if(tmp==0)break;
                addFirstEdge(i,tmp);
            }
        }
        for(int i=1;i<=n;i++)
            if(!low[i])tarjan(i);
        for(int i=1;i<=firstEdgeCnt;i++){
            int u=firstEdge[i].from;
            int v=firstEdge[i].to;
            if(c[u]!=c[v]){
                addSecondEdge(c[u],c[v]);
                rd[c[v]]++;
                cd[c[u]]++;
            }
        }
        int p=0,q=0; 
        for(int i=1;i<=sccCnt;i++){
            if(rd[i]==0)p++;
            if(cd[i]==0)q++;
        } 
        cout<<p<<endl;
        if(sccCnt==1)cout<<"0"<<endl;
        else cout<<max(p,q)<<endl;
        return 0;
    }
  • 相关阅读:
    模板汇总——Tarjian
    CountHunter 6101 最优贸易 强联通缩点
    POJ-3662 Telephone Lines 二分+双端队列
    EF-获取自增ID值
    EF-记录程序自动生成并执行的sql语句日志
    EF-使用迁移技术让程序自动更新数据库表结构
    EF-关于类库中EntityFramework之CodeFirst(代码优先)的操作浅析
    javascript进阶笔记(3)
    javascript进阶笔记(2)
    javascript进阶笔记(1)
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680595.html
Copyright © 2011-2022 走看看