• POJ 3177 Redundant Paths


    POJ_3177

    说实话,我现在还是不明白这个题目究竟是想让我们如何去处理问题。首先的疑惑就是如果连续输入两个1 212之间算一条路还是两条路,其次如果分别输入1 22 1,这时12之间算一条路还是两条路?

    由于对上面数据的理解的不同,会用3种不同的处理方式:

    ①不管1 2还是2 1,就当做是12之间连通,也就是完全忽略题目中所说的两点之间可以有多条路,多条时只当有一条。

    ②两个1 2看做一条路,1 22 1看做两条路。

    ③两个1 2看做两条路,1 22 1也看做两条路。

    其中根据①和②写出的程序都是可以AC的,而根据③写出的程序,依据我看到的一些讨论,应该是WA掉的。也正是因为这个,导致我对题意严重不解。

    如果按思路①很好写程序的,邻接矩阵实现起来可能更方便一点,因为输入的时候就不用判断是否有重边了,空间上也是允许的。

    这里再说一下我如果按思路②理解,我的一些想法。

    首先如果按②理解的话,邻接矩阵实现起来可能不大好实现,如果用邻接表的话,我们可以先当做有向边来读,将重边删去,最后再把每个边反向存一遍。然后其余的代码全部按思路①的模式去写。

    当然如果这么写代码,实际上就是按两点之间最多只有一条边来处理的,最后是求不出到底哪些是一起的边双连通分量的,但对结果没有什么影响。对于为什么没影响,我们可以枚举重边出现的位置来看一下。

    首先,如果重边出现在原本的边双连通分中,那么肯定没有影响。再者,如果重边出现在两个不是“叶子”的边连通分量之间的桥的位置,那么这时也不会有影响,因为我们最终统计的是“叶子”的个数,中间的部分是没有影响的。再者,如果重边出现在是“叶子”的边双连通分量与其他边连通分量之间,那么这时在没有重边时的“叶子”在重边出现后就不是“叶子”了,同时,由于多了一个重边,在计算原来的“叶子”的出入度时就会多算上这个重边的,于是出入度的值便不会再体现出作为“叶子”的特征,于是便不会再把这个边双连通分量再看做“叶子”而增加“叶子”的计数了,也便对最后“叶子”的计数是没有影响的。

    通过上面的分析表明,尽管我们最后得不到正确的边双连通分量,但对解题的结果是没有影响的,就好比强连通分量的题目中,我们以强连通分量中各个顶点的出度、入度的和作为这个强连通分量的出度、入度,尽管这样算出的出度、入度是不一定正确的,但对于我们统计出度为0和入度为0的强连通分量的个数是没有影响的。

    下面的是按思路②写成的代码。

    #include<stdio.h>
    #include
    <string.h>
    int first[5010],next[10010],v[10010],n,dgr[5010];
    int time,dfn[5010],low[5010],paint[5010],num,s[5010],top;
    void tarjan(int u,int fa)
    {
    int e;
    dfn[u]
    =low[u]=++time;
    s[top
    ++]=u;
    for(e=first[u];e!=-1;e=next[e])
    if(v[e]!=fa)
    {
    if(!dfn[v[e]])
    {
    tarjan(v[e],u);
    if(low[v[e]]<low[u])
    low[u]
    =low[v[e]];
    else if(low[v[e]]>dfn[u])
    {
    for(s[top]=-1;s[top]!=v[e];)
    paint[s[
    --top]]=num;
    num
    ++;
    }
    }
    else if(dfn[v[e]]<low[u])
    low[u]
    =dfn[v[e]];
    }
    }
    int main()
    {
    int i,j,k,r,a,b,u,e,leaves,temp,ok;
    while(scanf("%d%d",&n,&r)==2)
    {
    memset(first,
    -1,sizeof(first));
    e
    =0;
    for(i=0;i<r;i++)
    {
    scanf(
    "%d%d",&a,&b);
    a
    --;
    b
    --;
    ok
    =1;
    for(temp=first[a];temp!=-1;temp=next[temp])
    if(v[temp]==b)
    {
    ok
    =0;
    break;
    }
    if(ok)
    {
    v[e]
    =b;
    next[e]
    =first[a];
    first[a]
    =e;
    e
    ++;
    }
    }
    k
    =e;
    for(u=0;u<n;u++)
    for(temp=first[u];temp!=-1;temp=next[temp])
    if(temp<k)
    {
    v[e]
    =u;
    next[e]
    =first[v[temp]];
    first[v[temp]]
    =e;
    e
    ++;
    }
    memset(dfn,
    0,sizeof(dfn));
    time
    =top=0;
    memset(paint,
    0,sizeof(paint));
    num
    =1;
    for(i=0;i<n;i++)
    if(!dfn[i])
    tarjan(i,
    -1);
    memset(dgr,
    0,sizeof(dgr));
    for(u=0;u<n;u++)
    {
    for(e=first[u];e!=-1;e=next[e])
    if(paint[u]!=paint[v[e]])
    {
    dgr[paint[u]]
    ++;
    dgr[paint[v[e]]]
    ++;
    }
    }
    leaves
    =0;
    for(i=0;i<num;i++)
    if(dgr[i]==2)
    leaves
    ++;

    printf(
    "%d\n",(leaves+1)/2);
    }
    return 0;
    }

      

      

  • 相关阅读:
    CentOS7防火墙开启与关闭以及开放6379,3306,80等端口
    Linux 安装PHP PECL 百分百成功
    NSIS 无边框移动问题总结笔记
    Flask项目下的app下的settings.py配置
    django excel xlsx 中文编码
    django admin TabularInline raw_id_fields 添加查询 搜索小图标显示
    m3u8文件解密
    python3 tensorflow 试玩
    python3 tensorflow 安装
    Numpy&Pandas 学习
  • 原文地址:https://www.cnblogs.com/staginner/p/2137517.html
Copyright © 2020-2023  润新知