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;
    }
    
  • 相关阅读:
    debugs
    MySQL事务隔离级别详解(转)
    解决SQL Server管理器无法连接远程数据库的问题(转)
    jQuery中click(),bind(),live()的区别(转)
    各jQuery选择器的用法(转)
    使用JQuery获取对象的几种方式(转)
    HTML中元素的定位方式
    深入浅出REST(转载)
    jQuery-Selectors(选择器)的使用(二、层次篇)(转载)
    linux常用命令
  • 原文地址:https://www.cnblogs.com/tarjan/p/7462925.html
Copyright © 2011-2022 走看看