这题一开始看到是懵逼的,百度了很多题解也是懵逼的,以为是一个很难得图论问题,因为我图论也只会一些模版.但是后来仔细看发现其实这题不需要什么图的基础,也是一个思维题.
题目描述,需要这样一种路线,但是他区分不同的路线,是根据那些路走了两遍,那些路走了一遍来的,而不是行走顺序,这一点首先要看清楚.
第二呢,注意到这种路线满足所有点都被经过的特点,所以这是欧拉通路的定义,如果不知道可以百度,很简单的.
所以现在就是一个计数问题,找到所有将m-2条边复制一次,使得图满足欧拉通路定义即可.
不复制的两条边分三种情况.
1.都是自环,显然可以,为C(loop,2).
2.一自环一非自环,为loop*(m-loop).
3.两个非自环,注意需要满足他们接在同一个点上,所以为
for(所有点)
ans+=C(非自环边数,2).
/* xzppp */
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <list>
using namespace std;
#define FFF freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mp make_pair
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 1000000;
const LL INF = 0x7fffffffffffffff;
const int MOD = 1e9+7;
int vis[MAXN+17],self[MAXN+17];
vector<int> G[MAXN+17];
void dfs(int x)
{
for (int i = 0; i < G[x].size(); ++i)
if(vis[G[x][i]]==2)
{
vis[G[x][i]]=1;
dfs(G[x][i]);
}
}
int main()
{
//FFF
LL n,m,loop=0,cnt=0;
cin>>n>>m;
for (int i = 0; i < m; ++i)
{
int u,v;
scanf("%d%d",&u,&v);
u--;
v--;
if(u==v)
{
loop++;
self[u] = 1;
}
else
{
G[u].push_back(v);
G[v].push_back(u);
}
vis[v]=vis[u]=2;
}
bool can = true;
for (int i = 0; i < n; ++i)
{
if(vis[i]==2)
{
dfs(i);
if(++cnt>1)
{
can = false;
break;
}
}
}
LL ans = 0;
if(can)
{
for(int i=0;i<n;++i)
{
int num = G[i].size();
ans+=(1LL*num*(num-1))/2;
}
}
ans += (1LL*(loop-1)*loop)/2;
ans += 1LL*loop*(m-loop);
if(can)
cout<<ans<<endl;
else
cout<<"0"<<endl;
return 0;
}