• 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;
    }
  • 相关阅读:
    CentOS中基于不同版本安装重复包的解决方案
    诺讯科技
    SQLMap使用
    python初码
    优秀软件project师必备的7大特性
    3.2 Piecewise Linear Interpolation(站点)
    C#开发Unity游戏教程之游戏对象的属性变量
    java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4
    一键解决ScrollView嵌套ListView仅仅显示一行的问题
    W5500中断寄存器的理解
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/7845879.html
Copyright © 2020-2023  润新知