codeforces 789 D Weird journey
题意:给你n个点,m条边,问你能不能在m-2条边上面,每条边走两次,剩下两条边走一次
题解:将m-2条边看成2*(m-2)条边,并且不会重复走这个2*(m-2)条边,很显然这个是欧拉回路,那么根据欧拉回路的定义,每个点都有偶数度,因此剩下的两个边必须连在同一个点上。也就是说只要枚举每个点,任意选两个与他相邻的点连线作为这两条边。ans+=C(vec[i].size(),2);但是还要考虑自环的存在,因为一个自环是对一个点度数加2,因此他可以和任意边组合,最后还要减去重复的情况。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <queue> #include <vector> #include <cstring> #include <iomanip> #include <set> #include<ctime> //CLOCKS_PER_SEC #define se second #define fi first #define ll long long #define Pii pair<int,int> #define Pli pair<ll,int> #define ull unsigned long long #define pb push_back #define fio ios::sync_with_stdio(false);cin.tie(0) const double Pi=3.14159265; const int N=1e6+10; const ull base=163; const int INF=0x3f3f3f3f; using namespace std; vector<int>vec[N]; bool vis[N]; void dfs(int u){ vis[u]=1; for(int i=0;i<vec[u].size();i++){ int v=vec[u][i]; if(vis[v])continue; dfs(v); } } bool vs[N]; int main(){ fio; ll n,m; cin>>n>>m; ll t=0; for(int i=1;i<=m;i++){ int u,v; cin>>u>>v; vs[u]=vs[v]=1; if(u==v){t++;continue;} vec[u].pb(v),vec[v].pb(u); } for(int i=1;i<=n;i++){ if(vec[i].size()>0){ dfs(i); break; } } for(int i=1;i<=n;i++){ if(!vis[i]){ if(vs[i]>0)return cout<<0,0; } } ll sum=0; for(int i=1;i<=n;i++){ sum+=1LL*vec[i].size()*(1LL*vec[i].size()-1LL)/2LL; } cout<<sum+t*(m-1)-t*(t-1LL)/2LL; return 0; }