zoukankan      html  css  js  c++  java
  • codeforces 789D. Weird journey(欧拉回路,想法题)

    题目链接

    D. Weird journey
    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Little boy Igor wants to become a traveller. At first, he decided to visit all the cities of his motherland — Uzhlyandia.

    It is widely known that Uzhlyandia has n cities connected with m bidirectional roads. Also, there are no two roads in the country that connect the same pair of cities, but roads starting and ending in the same city can exist. Igor wants to plan his journey beforehand. Boy thinks a path is good if the path goes over m - 2 roads twice, and over the other 2 exactly once. The good path can start and finish in any city of Uzhlyandia.

    Now he wants to know how many different good paths are in Uzhlyandia. Two paths are considered different if the sets of roads the paths goes over exactly once differ. Help Igor — calculate the number of good paths.

    Input
    The first line contains two integers n, m (1 ≤ n, m ≤ 106) — the number of cities and roads in Uzhlyandia, respectively.

    Each of the next m lines contains two integers u and v (1 ≤ u, v ≤ n) that mean that there is road between cities u and v.

    It is guaranteed that no road will be given in the input twice. That also means that for every city there is no more than one road that connects the city to itself.

    Output
    Print out the only integer — the number of good paths in Uzhlyandia.

    Examples
    input
    5 4
    1 2
    1 3
    1 4
    1 5
    output
    6
    input
    5 3
    1 2
    2 3
    4 5
    output
    0
    input
    2 2
    1 1
    1 2
    output
    1
    Note
    In first sample test case the good paths are:

    2 → 1 → 3 → 1 → 4 → 1 → 5,
    2 → 1 → 3 → 1 → 5 → 1 → 4,
    2 → 1 → 4 → 1 → 5 → 1 → 3,
    3 → 1 → 2 → 1 → 4 → 1 → 5,
    3 → 1 → 2 → 1 → 5 → 1 → 4,
    4 → 1 → 2 → 1 → 3 → 1 → 5.
    There are good paths that are same with displayed above, because the sets of roads they pass over once are same:

    2 → 1 → 4 → 1 → 3 → 1 → 5,
    2 → 1 → 5 → 1 → 3 → 1 → 4,
    2 → 1 → 5 → 1 → 4 → 1 → 3,
    3 → 1 → 4 → 1 → 2 → 1 → 5,
    3 → 1 → 5 → 1 → 2 → 1 → 4,
    4 → 1 → 3 → 1 → 2 → 1 → 5,
    and all the paths in the other direction.
    Thus, the answer is 6.

    In the second test case, Igor simply can not walk by all the roads.

    In the third case, Igor walks once over every road.

    题意:给出 (n) 个点 (m) 条边的无向图,问 从任意顶点出发,任意顶点结束使得 (m-2) 条边走两次,剩下 (2) 条边走一次的不同路径方案数,注意此处不同方案指的是路径走过的边的集合不同。

    题解:当图连通时,由于不同方案指的是路径走过的边的集合不同,那么我们可以枚举哪两条边只走了一次,原问题就相当于将原来的边集( imes 2) ,那么每个点都是度为偶数,此时存在欧拉回路,而现在要去掉两条边,使得仍然存在欧拉回路。分情况讨论:

    1.去掉的两条边都不是自环,若这两条边没有公共顶点,那么就会产生 (4) 个奇点,显然不存在欧拉回路,因此这两条边必须存在公共顶点。

    2.如果去掉的边中有一个为自环,那么另外一条边随意了,可以是其他的所有边(包括自环边)。

    同时,要注意这么算当两条边同时为自环时情况算了两次,要减去。

    同时,当图不联通时,要特判孤点的情况,孤点是可以存在的。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<stack>
    using namespace std;
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=n-1;i>=a;i--)
    #define pb push_back
    #define fi first
    #define se second
    #define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;
    typedef vector<int> VI;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=1e6+10;
    int deg[maxn],num[maxn];
    int pa[maxn];
    int find(int x)
    {
        return pa[x]==x? x:pa[x]=find(pa[x]);
    }
    int vis[maxn];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        rep(i,1,n+1) pa[i]=i;
        rep(k,0,m)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            if(u==v)
            {
                num[u]++;
            }
            else
            {
                deg[u]++,deg[v]++;
                int fu=find(u),fv=find(v);
                if(fv!=fu) pa[fv]=fu;
            }
            vis[u]=vis[v]=1;
        }
        int cnt=0;
        rep(i,1,n+1) if(pa[i]==i&&vis[i]) cnt++;
        if(cnt>=2)
        {
            return 0*puts("0");
        }
        ll ans=0;
        rep(i,1,n+1)
        {
            ans+=1ll*deg[i]*(deg[i]-1)/2;
            ans+=1ll*num[i]*(m-1);
        }
        int tot=0;
        rep(i,1,n+1) tot+=num[i];
        ans-=1ll*tot*(tot-1)/2;
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    移动端touch事件获取事件坐标
    详解webpack中的hash、chunkhash、contenthash区别
    textarea placeholder 设置主动换行
    js-xlsx的使用
    关于Blob对象的介绍与使用
    spring boot zuul集成kubernetes等第三方登录
    Spring Boot 获取yaml配置文件信息
    spring boot @Value源码解析
    java.lang.StackOverflowError解决
    Jpa 重写方言dialect 使用oracle / mysql 数据库自定义函数
  • 原文地址:https://www.cnblogs.com/tarjan/p/7462925.html
Copyright © 2011-2022 走看看