• hdu 4005 边连通度与缩点


    思路:先将图进行缩点,建成一颗树,那么如果这是一条单路径树(即最大点度不超过2),就不在能删的一条边,使得不连通。因为将其头尾相连,形成一个圈,那么删任意一条边,图都是连通的。

    上面的是无解的情况,如果有解,那么这个解一定是树中不全在一条路径上的三条边中的一条,使得这三条边中的最大边最小,即得解。同样,对任意一个节点,其三个子树上的边一定是三条不全在一条路径上的边。问题就转化为求一个节点的第三小边。

    但直接求第三小边容易出错,并且不易求得。我们可以先选一条树中的最小边,这条边一定是三条边中的一条,我们就沿着这条边的两个端点找。那么问题就又变成了求一个节点的次小边了。这个很容易求得。


    感谢http://www.cnblogs.com/wuyiqi/archive/2011/11/04/2235671.html提供的测试数据。

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #define Maxn 10010
    #define Maxm 200010
    #define inf 0x7fffffff
    using namespace std;
    int dfn[Maxn],low[Maxn],vi[Maxn],head[Maxn],Stack[Maxn],id[Maxn],degree[Maxn],lab,e,n,top,num,m,ans,wer[Maxn][2];
    struct Edge{
        int u,v,next,f,val;
    }edge[Maxm];
    void init()
    {
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(vi,0,sizeof(vi));
        memset(id,0,sizeof(id));
        memset(degree,0,sizeof(degree));
        memset(head,-1,sizeof(head));
        lab=top=e=num=0;
        ans=inf;
    }
    inline int Max(int a,int b,int c)
    {
        int temp=a>b?a:b;
        return temp>c?temp:c;
    }
    void add(int u,int v,int val)
    {
        edge[e].u=u,edge[e].v=v,edge[e].f=0,edge[e].val=val,edge[e].next=head[u],head[u]=e++;
        edge[e].u=v,edge[e].v=u,edge[e].f=0,edge[e].val=val,edge[e].next=head[v],head[v]=e++;
    }
    void Tarjan(int u)
    {
        int i,v;
        dfn[u]=low[u]=++lab;
        Stack[top++]=u;
        vi[u]=1;
        for(i=head[u];i!=-1;i=edge[i].next)
        {
            if(edge[i].f) continue;
            edge[i].f=edge[i^1].f=1;
            v=edge[i].v;
            if(!dfn[v])
            {
                Tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            if(vi[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u])
        {
            ++num;
            do{
                i=Stack[--top];
                id[i]=num;
                vi[i]=0;
            }while(i!=u);
        }
    }
    int dfs(int u,int f)
    {
        int i,v;
        int temp;
        wer[u][0]=wer[u][1]=inf;
        for(i=head[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].v;
            if(v==f) continue;
            temp=edge[i].val;
            temp=min(temp,dfs(v,u));
            if(temp<wer[u][0])
            {
                wer[u][1]=wer[u][0];
                wer[u][0]=temp;
            }
            else
            if(temp<wer[u][1])
                wer[u][1]=temp;
            ans=min(ans,wer[u][1]);
        }
        return wer[u][0];
    }
    int solve()
    {
        int i,j,u,v;
        Tarjan(1);
        int en=e;
        int Maxdegree=0;
        memset(head,-1,sizeof(head));
        e=0;
        int Minedge=inf,choice;
        for(i=0;i<en-1;i+=2)
        {
            u=edge[i].u,v=edge[i].v;
            if(id[u]!=id[v])
            {
                add(id[u],id[v],edge[i].val);
                if(edge[i].val<Minedge)
                {
                    Minedge=edge[i].val,choice=e-1;
                }
                degree[id[u]]++,degree[id[v]]++;
                Maxdegree=Max(Maxdegree,degree[id[u]],degree[id[v]]);
            }
        }
        if(Maxdegree<=2)
            return 0;
        u=edge[choice].u,v=edge[choice].v;
        dfs(u,v);
        dfs(v,u);
        return 1;
    }
    int main()
    {
        int i,j,a,b,c;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                add(a,b,c);
            }
            if(!solve())
                printf("-1
    ");
            else
                printf("%d
    ",ans);
        }
        return 0;
    }

    /*
    6
    2 2
    3 6
    4 3
    5 4
    6 5
    7 7
    15 14
    2 7
    4 5
    5 6
    8 1
    9 2
    10 3
    11 4
    3 8
    6 9
    7 1
    12 11
    13 12
    14 13
    15 14
    16 15
    2 7
    4 5
    5 6
    8 1
    9 2
    10 3
    11 4
    16 1
    3 6
    6 9
    7 1
    12 11
    13 12
    14 13
    15 14
    6 5
    2 1
    3 2
    4 3
    5 4
    6 5
    9 8
    2 1
    6 5
    7 7
    8 4
    9 6
    3 2
    4 5
    5 6
    9 8
    2 1
    6 5
    7 7
    8 4
    9 4
    3 2
    4 5
    5 6
    4*/ 

  • 相关阅读:
    ps 允许执行不信任的脚本
    mysql 某表某列支持 emoji
    jenkins
    成为真正的win10 超级管理员,解决win+r 不以管理员身份运行
    bat curl 定时请求
    jq 日期区间处理
    jq 日期区间处理
    ubuntu cli
    nginx启动两个flask项目
    nginx 配置http和https验证
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3244591.html
Copyright © 2020-2023  润新知