[题解]洛谷P2863 [USACO06JAN]牛的舞会The Cow Prom

思路

  刚学会tarjan。。发现一道tarjan的模板题

  直接跑tarjan出栈时统计

  需要注意的是:

  千万不要用stl栈!我再也不用stl了,卡爆。。。(╯°Д°)╯︵┻━┻

  (其实这是我第一次手写stack)

代码

  

#include<cstdio>
#include<algorithm>
#include<cstring>
//#include<stack>
using namespace std;

const int MAXN=10010,MAXM=50010;

int n,m,ans=0;
int first[MAXN];

struct edge{
    int u,v,next;
}e[MAXM];

int tot=0;
void insert(int u,int v){
    tot++;e[tot].u=u;e[tot].v=v;e[tot].next=first[u];first[u]=tot;
}

//stack<int> s;
int stack[MAXN],top=0;
int deepdark=0;
int dfn[MAXN]={0},low[MAXN]={0},ins[MAXN]={0};
void tarjan(int u){
    dfn[u]=low[u]=++deepdark;
    ins[u]=1;
    //s.push(u);
    top++;stack[top]=u;
    for(int i=first[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(dfn[v]==0){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v]){
            low[u]=min(low[u],dfn[v]);
        }
    }
    if(dfn[u]==low[u]){
        int qwq=0;
        while(s.top()!=u){
            ins[/*s.top()*/stack[top]]=0;
            //s.pop();
            top--;
            qwq++;
        }
        ins[u]=0;//s.pop();
        top--;
        qwq++;
        if(qwq>1)ans++;
    }
}

int main(){
    memset(first,-1,sizeof(first));
    scanf("%d%d",&n,&m);
    int x,y;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        insert(x,y);
    }
    for(int i=1;i<=n;i++){
        if(dfn[i]==0){
            tarjan(i);
        }
    }
    printf("%d",ans);
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/sjrb/p/10336908.html