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;
    }
    
  • 相关阅读:
    【css】border-image
    函数的调用
    函数的返回值
    定义函数的三种形式
    文件处理实战之购物车系统
    文件处理小结
    文件修改的两种方式
    with管理文件操作上下文
    绝对路径和相对路径
    基本的文件操作
  • 原文地址:https://www.cnblogs.com/tarjan/p/7462925.html
Copyright © 2011-2022 走看看