zoukankan      html  css  js  c++  java
  • bzoj 2935 [Poi1999]原始生物——欧拉回路思路!

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2935

    有向图用最小的路径(==总点数最少)覆盖所有边。

    完了完了我居然连1999年的题都做不出来了。

    TJ:https://blog.csdn.net/u014609452/article/details/53705451

    仔细一想,原来就是欧拉回路的连通块自然不用说,原来不是欧拉回路的连通块,我们在走路径的时候不时从一个点跳到另一个点,其实可以看作是给这两个点间连了一条边!

    所以手动连一个欧拉回路。这样应该一定是最小的。

    因为是欧拉回路,所以有点浪费。因为其实欧拉路就可以了,只是我们不会连成欧拉路罢了。

    考虑把自己连的一条边当做路径的开始或结尾,这样就可以不走那条边,从而变成欧拉路。体现在答案上就是少了一个点,点数==删边前边数。

    TJ的代码实现这一过程写得太好啦!无耻默写。

    所以需要回顾!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1000;
    int n,sum,deg[N+5],fa[N+5],ans;
    bool tag[N+5],vis[N+5];
    int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
    int main()
    {
        for(int i=1;i<=N;i++)fa[i]=i;
        scanf("%d",&n);int x,y;ans=n;//原边数 
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            vis[x]=1;vis[y]=1;
            deg[x]++;deg[y]--;
            if(find(x)!=find(y))fa[find(x)]=find(y);
        }
        for(int i=1;i<=N;i++)
            if(vis[i]&&deg[i])tag[find(i)]=1;
        for(int i=1;i<=N;i++)
            if(vis[i]&&fa[i]==i&&!tag[i])ans++;//原欧拉回路+1 
        for(int i=1;i<=N;i++)
            sum+=(deg[i]>0?deg[i]:-deg[i]);//补的边 
        ans+=sum/2;
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    G
    C
    B
    B
    线段树模板
    网络流模板
    POJ_1631_Bridging_Signals_(动态规划,LIS)
    POJ_1065_Wooden_Sticks_(动态规划,LIS+鸽笼原理)
    BZOJ_1015_星球大战_[JSOI2008]_(并查集)
    POJ_3280_Cheapest_Palindrome_(动态规划)
  • 原文地址:https://www.cnblogs.com/Narh/p/9282188.html
Copyright © 2011-2022 走看看