题目原文:http://codeforces.com/problemset/problem/788/B
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.
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.
Print out the only integer — the number of good paths in Uzhlyandia.
题目大意:总共有n个节点,m条路径,要求其中m-2条路径走两遍,剩下2条路径仅走一遍,问不同的路径总数有多少,如果仅走一遍的两条边不同则将这两条路径视为不同。
解题思路:
可将那m-2条边,每条边拆为两条重边,所以这些边连接的点的度数肯定都是偶数,接下来考虑最后两条边,先不考虑自环的情况,那么如果这两条边没有公共顶点的话,那么会产生4个奇数度定点,不满足欧拉路的条件,所以这两边一定会有公共顶点,这样只会产生2个奇数度的定点,满足欧拉回路。所以只需要从每个点连出的 x 条边(不考虑自环)中选出两条即可。
再来考虑自环的情况,自环的边不会产生奇数度定点,所以他可以和任意的边进行组合,最后再减去重复考虑的情况就是答案。
对于不联通的情况直接输出0.
AC代码:
/*
@Author: wchhlbt
@Date: 2017/3/29
*/
#include <bits/stdc++.h>
#define Fori(x) for(int i=0;i<x;i++)
#define Forj(x) for(int j=0;j<x;j++)
#define maxn 1110007
#define inf 0x3f3f3f3f
#define ONES(x) __builtin_popcount(x)
using namespace std;
typedef long long ll ;
const double eps =1e-8;
const int mod = 10007;
const double PI = acos(-1.0);
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
vector<int> e[maxn];
int vis[maxn];
int deg[maxn];
void dfs(int u)
{
vis[u] = 1;
for(int i = 0; i<e[u].size(); i++){
int v = e[u][i];
if(!vis[v])
dfs(v);
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
ll cnt = 0;
for(int i = 1; i<=m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
deg[u]++; deg[v]++;
if(u!=v){
e[u].push_back(v);
e[v].push_back(u);
}
else
cnt++;
}
for(int i = 1; i<=n; i++){
if(e[i].size()){
dfs(i);
break;
}
}
ll ans = 0;
for(int i = 1; i<=n; i++){
if(vis[i]==0 && deg[i]){
puts("0");
return 0;
}
}
for(int i = 0; i<=n; i++){
ans += 1ll*e[i].size()*(e[i].size()-1)/2;
}
ans = ans + cnt*(m-1) - cnt*(cnt-1)/2;
printf("%I64d\n",ans);
}

本文解析了一道Codeforces上的竞赛题目,题目要求计算特定类型的路径数量。通过分析可知,需构造欧拉回路并考虑自环的影响。最终,提供了一个有效的算法实现方案。
&spm=1001.2101.3001.5002&articleId=68927689&d=1&t=3&u=d5d659918dff4ac481ca11640c99bcee)
1072

被折叠的 条评论
为什么被折叠?



