zoukankan      html  css  js  c++  java
  • POJ3177:Redundant Paths——题解

    http://poj.org/problem?id=3177

    明显要求桥的一道题。

    (因为有桥就说明只能从那一条路走,换句话说就是只有一种方法)

    求完桥后按照结论(加几条边成双连通图的结论,不会请baidu)就可以输出ans啦!

    (为此学了一下新的桥的求法……原来的那个常数太大了)

    #include<stack>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    inline int read(){
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*w;
    }
    const int maxn=5001;
    int cnt=1,head[maxn];
    struct node{
        int w;
        int ed;
        int nxt;
        int st;
    }edge[20001];
    void add(int u,int v){
        cnt++;
        edge[cnt].ed=v;
        edge[cnt].st=u;
        edge[cnt].nxt=head[u];
        head[u]=cnt;
        return;
    }
    bool bridge[20001];
    int dfn[maxn];
    int low[maxn];
    bool instack[maxn];
    int fa[maxn];
    int from[maxn];
    int indeg[maxn];
    int t=0;
    void tarjan(int u){
        t++;
        dfn[u]=t;
        low[u]=t;
        for(int i=head[u];i;i=edge[i].nxt){
        if(i==(from[u]^1))continue;
        int v=edge[i].ed;
        if(!dfn[v]){
            from[v]=i;
            tarjan(v);
            low[u]=min(low[u],low[v]);
            if(low[v]>dfn[u])bridge[from[v]]=bridge[from[v]^1]=1;
        }else{
            low[u]=min(low[u],dfn[v]);
        }
        }
        return;
    }
    int find(int a){
        if(fa[a]==a)return a;
        return fa[a]=find(fa[a]);
    }
    int main(){
        int f=read();
        int r=read();
        for(int i=1;i<=r;i++){
        int u=read();
        int v=read();
        add(u,v);
        add(v,u);
        }
        tarjan(1);
        for(int i=1;i<=f;i++)fa[i]=i;
        for(int i=2;i<=cnt;i+=2){
        if(!bridge[i])fa[find(edge[i].st)]=find(edge[i].ed);
        }
        for(int i=2;i<=cnt;i+=2){
        if(bridge[i])indeg[find(edge[i].st)]++,indeg[find(edge[i].ed)]++;
        }
        int leaf=0;
        for(int i=1;i<=f;i++){
        if(find(i)==i){
            if(indeg[i]==1)leaf++;
        }
        }
        printf("%d
    ",(leaf+1)/2);
        return 0;
    }
  • 相关阅读:
    SQLServer 时间差运算
    phpStudy
    解决Apache/PHP无法启动的问题
    apche的主配置文件)
    知识总结
    学完了js的知识,一起分享总结知识点
    JS的学习体会与分享
    SpringBoot -- pom.xml文件
    c++基本知识点
    c语言基本常识5
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/7845879.html
Copyright © 2011-2022 走看看