• CodeForces 788B


    题意:

             给出无向图.

             good way : 仅有两条边只经过一次,余下边全经过两次的路

             问你共有多少条不同的good way。

             两条good way不同仅当它们所经过的边的集合中至少有一条不同 (很关键)

             存在多个边连通分量的情况肯定是0.

             当确定某两条边只经过一次的时候:

                       由于经过边的顺序不重要,余下边全经过两次,至多只有一条good way

                       那么把剩下经过两次的边拆分成两条经过一次的边,记现在的图是新图

                       原图中是否存在good way 就等价于新图中是否存在欧拉路

            

             暴力枚举两条边判断肯定是要TLE的

             那就要考虑怎样的两条边存在解

            

             先不考虑自环:

                       当这两条边不相邻时:

                                由于只有这两条边的端点的度是奇数,其他点都是偶数,新图中共有四个点是奇数度,不存在欧拉路

                       当这两条边相邻时:

                                这两条边的三个端点中两个是奇数,余下都是偶数,存在欧拉回路

             考虑自环

                       当其中有一条边是自环时:

                                自环只有一个端点,故自环的端点是偶数度,新图中只有两个奇数度点,存在欧拉回路

                       当两条边都是自环时:

                                所有点都是偶数度,存在欧拉回路

             故存在解的情况:

                       两条边相邻 (去掉自环后的边):

                                枚举每个端点i, ans += Comb(edge[i].size(), 2);

                       其中一条边是自环:

                                ans += loopCnt * (m-1);

                                ans -= Comb(loopCnt, 2);//重复计算

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 const int MAXN = 1000005;
     5 int n, m;
     6 vector<int> G[MAXN];
     7 int loop[MAXN], lcnt;
     8 int vis[MAXN];
     9 void dfs(int x)
    10 {
    11     if (vis[x]) return;
    12     vis[x] = 1;
    13     for (int i = 0; i < G[x].size(); i++)
    14         dfs(G[x][i]);
    15 }
    16 int main()
    17 {
    18     for (int i = 1; i <= n; i++)
    19         G[i].clear(), vis[i] = loop[i] = 0;
    20     lcnt = 0;
    21     scanf("%d%d", &n, &m);
    22     int root;
    23     for (int i = 1; i <= m; i++)
    24     {
    25         int x, y; scanf("%d%d", &x, &y);
    26         if (x == y) loop[x]++ ,lcnt++;
    27         else
    28         {
    29             G[x].push_back(y);
    30             G[y].push_back(x);
    31         }
    32         root = x;
    33     }
    34     dfs(root);
    35     bool flag = 1;
    36     for (int i = 1; i <= n; i++)
    37     {
    38         if (!vis[i] && (G[i].size() || loop[i]))
    39             flag = 0;
    40     }
    41     if (!flag)
    42     {
    43         puts("0"); return 0;
    44     }
    45     LL ans = 0;
    46     for (int i = 1; i <= n; i++)
    47     {
    48         int sz = G[i].size();
    49         ans += (LL)sz*(sz-1) / 2;
    50     }
    51     ans += (LL)lcnt * (m-1);
    52     ans -= (LL)lcnt * (lcnt-1) / 2;
    53     printf("%lld
    ", ans);
    54 }
    View Code
    我自倾杯,君且随意
  • 相关阅读:
    Node.js 回调函数
    算法二、
    一、Perfect Squares 完全平方数
    Never Go Away
    python 内置方法
    web框架详解之tornado 三 url和分页
    web框架详解之tornado 二 cookie
    前端各种插件
    AJAX请求时status返回状态明细表
    LR之-参数化
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/6646266.html
Copyright © 2020-2023  润新知