您的位置:首页 > 其它

CodeForces - 788B Weird journey(欧拉回路)

2017-12-02 18:43 381 查看
点击打开题目链接

B. Weird journey

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard 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.
<
4000
p style="margin-top:1.5em;margin-bottom:0px;padding-top:0px;padding-bottom:0px;font-size:1em;line-height:1.4em;">
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条路中有m-2条路走两次,剩余2条路走一次,并且遍历所有城市的方案数。(两个方案被认为是不同的,当走一次的路不相同时)

思路:

首先判断是否连通,不连通输出0.

然后考虑所有路都走两次,相当于某种路线方案走两次,一次去,一次回。

问题则转化成了怎样去掉两条边使得剩余路线满足欧拉通路。即最多两个点的度数为奇数。

1.去掉任意两个自环后所有点度数还是偶数,满足条件。

2.去掉一个自环和剩下任意一条边,多出两个奇度点,满足条件。

3.去掉两条非自环的边,且没有公共点,多出4个奇度点,不满足条件。

4.去掉两条非自环的边,有公共点,多出2个奇度点,满足条件。

分类加上满足条件的情况即可。

错了两次,一次是寻找起点进行dfs时判断条件不应该看度数是否非0,应该看该点公共边是否非0(自环)。第二次乘积时应转为long long.

代码:

#include<iostream>
#include<vector>

using namespace std;
const int maxn = 1e6 + 5;
int in[maxn];//记录入度
int vis[maxn];
int n, m;
long long cnt;//记录自环数
vector<int>_map[maxn];//邻接表存图

//dfs遍历判断连通
void dfs(int u) {
vis[u] = 1;
for(int i = 0; i < _map[u].size(); i++) {
int v = _map[u][i];
if(!vis[v])
dfs(v);
}
}

int main() {
ios::sync_with_stdio(false);
cin >> n >> m;
for(int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
if(u == v) {
cnt++;
}
else {
_map[u].push_back(v);
_map[v].push_back(u);
}
in[u]++;
in[v]++;
}
for(int i = 1; i <= n; i++) {
if(_map[i].size()) {
dfs(i);
break;
}
}
//判断是否连通
for(int i = 1; i <= n; i++) {
if(in[i] && !vis[i]) {
cout << 0 << endl;
return 0;
}
}
long long ans = 0;
ans += cnt * (cnt-1) / 2;//自环和自环
ans += cnt * (m - cnt);//自环和任意非自环边
for(int i = 1; i <= n; i++) {
ans += 1LL * _map[i].size() * (_map[i].size() - 1) / 2;//该公共点的两条边
}
cout << ans << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: