冗余路径Redundant Paths

题面

tarjan 割点

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn=5010;
const int maxm=20010;
int n,m,u[maxn],v[maxn],x,y,cur,h[maxn],nxt[maxm],p[maxm],index_,dfn[maxn],low[maxn],bcc[maxn],deg[maxn],ans,ltt;
bool tf[maxm];
stack<int>st;
inline void add_edge(int x,int y)
{
    cur++;
    nxt[cur]=h[x];
    h[x]=cur;
    p[cur]=y;
}
void dfs(int cur)
{
    dfn[cur]=low[cur]=++index_;
    for(int j=h[cur];j!=-1;j=nxt[j])if(tf[j])
    {
        int i=p[j];
        if(dfn[i])low[cur]=min(low[cur],dfn[i]);
        else
        {
            st.push(i);
            tf[j]=tf[(j&1)?j+1:j-1]=false;
            dfs(i);
            tf[j]=tf[(j&1)?j+1:j-1]=true;
            low[cur]=min(low[cur],low[i]);
        }
    }
    if(dfn[cur]==low[cur])
    {
        ans++;
        while(!st.empty())
        {
            bcc[st.top()]=ans;
            if(st.top()==cur){st.pop();break;} 
            st.pop();
        }
    } 
}
int main()
{
    memset(h,-1,sizeof h);
    memset(tf,true,sizeof tf);
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d%d",u+i,v+i),add_edge(u[i],v[i]),add_edge(v[i],u[i]);
    for(int i=1;i<=n;i++)if(!dfn[i])ans=0,st.push(i),dfs(i);
    for(int i=0;i<m;i++)if(bcc[u[i]]!=bcc[v[i]])deg[bcc[u[i]]]++,deg[bcc[v[i]]]++;
    for(int i=1;i<=n;i++)if(deg[i]==1)ltt++;
    printf("%d\n",(ltt+1)/2);
    return 0;
}

 

posted @ 2019-07-09 13:41  [jackeylove]  阅读(170)  评论(0编辑  收藏  举报