HDU - 4738 有重边的割边 另附割点割边模板

题目链接 :https://vjudge.net/problem/HDU-4738

 

题目思路:思路很显然,就是求最小割边

                  坑点:有重复边,当最后求出来是0时,还需要1个人去,整个图本来就不是连通时,输出0

 

AC代码

#include 
#include
using namespace std;

#define N 1100
#define inf 0x3f3f3f3f
int n,m;
int dfn[N];
int low[N];
int first[N];
int bridge;
int edge_num;
int tt;
int vcut[N];
int father[N];
struct edge{
    int u,v;
    int w;
    int next;
    int flag;
}e[2*N*N];

void init()
{
    memset(first,-1,sizeof(first));
    edge_num=0;
    tt=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(vcut,0,sizeof(vcut));
    for(int i=1;i<=n;++i)
        father[i]=i;
}

int find(int x)
{
    if(father[x]!=x)
        return father[x]=find(father[x]);
    return x;
}

void merge(int a,int b)
{
    a=find(a);
    b=find(b);
    if(a!=b)
        father[a]=b;
}

void add_edge(int u,int v,int w)
{
    e[edge_num].u=u;
    e[edge_num].v=v;
    e[edge_num].w=w;
    e[edge_num].next=first[u];
    e[edge_num].flag=0;
    first[u]=edge_num++;
}

void Targin(int x,int pre)
{
    dfn[x]=low[x]=++tt;
    int pre_num=0;
    int son=0;
    for(int i=first[x];i!=-1;i=e[i].next)
    {
        int v=e[i].v;
        if(v==pre&&!pre_num)
        {
            pre_num++;
            continue;
        }
        if(!dfn[v])
        {
            son++;
            Targin(v,x);
            low[x]=min(low[x],low[v]);
            if(low[v]>low[x])
            {
                bridge++;
                e[i].flag=1;
                e[i^1].flag=1;
            }
            if(low[x]>=dfn[x])
            {
                vcut[x]=1;
            }
        }
        else
            low[x]=min(low[x],low[v]);
    }
    if(x==pre&&son>1)
        vcut[x]=son-1;
}

int main()
{
    while(scanf("%d%d",&n,&m))
    {
        if(n+m==0)
            break;
        init();
        for(int i=1;i<=m;++i)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add_edge(a,b,c);
            add_edge(b,a,c);
            merge(a,b);
        }
        int cnt=0;
        for(int i=1;i<=n;++i)
            if(father[i]==i)
                cnt++;
        if(cnt>1)
        {
            printf("0\n");
            continue;
        }
        Targin(1,1);
        int ans=inf;
        for(int i=0;ie[i].w)
                ans=e[i].w;
        }
        if(ans==inf)
            printf("-1\n");
        else
        {
            if(ans==0)
                printf("1\n");
            else
                printf("%d\n",ans);
        }

    }

    return 0;
}

 

你可能感兴趣的:(图论)