Codeforces 788B Weird journey(欧拉回路)

来源:互联网 发布:os系统教程加装windows 编辑:程序博客网 时间:2024/05/28 01:36

题意

n个点和m 条路,求 m2条边经过两次,2 条边经过一次的路有多少种。(无重边)


分析

先要判断除去孤点后,图是否联通,不联通则为0

先考虑每条路都走两遍,则每条边复制一遍,因此每个点的度都为偶数,则必有欧拉回路。

再删除两条边,看是否还是欧拉通路,则有以下四种情况:
①删去的2条边都是自环:删去后所有的点的度仍然是偶数,成立。
②删去的2条边中一条是自环:删去后只有2个点的度是奇数,成立。
③删去的2条边不是自环,且有公共点:删去后只有2个点的度是奇数,成立。
④删去的2条边不是自环,且无公共点:删去后有4个点的度是奇数,不成立。

所以只要累加前三种情况则是答案。

枚举每条边。
为非自环的边,ans+=2+
为自环的边,ans+=m1。(任意去掉另一条边都可以)
最后将ans/2去掉重复情况。


代码

#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<cctype>#include<set>#include<map>#include<queue>#include<stack>#include<iomanip>#include<sstream>#include<limits>#define ll long long#define inf 0x3f3f3f3fusing namespace std;const ll INF = 1e18;const int maxn = 2e6+10;const ll MOD = 1000000007;const double EPS = 1e-10;const double Pi = acos(-1.0);struct Edge{    int u,v;}a[maxn];vector<int>G[maxn];int inq[maxn];bool vis[maxn];void dfs(int u){    vis[u] = true;    for(int i = 0; i < G[u].size(); i++)    {        int to = G[u][i];        if (!vis[to]) dfs(to);    }}int main(){#ifdef LOCAL    //freopen("C:\\Users\\lanjiaming\\Desktop\\acm\\in.txt","r",stdin);    //freopen("output.txt","w",stdout);#endif//ios_base::sync_with_stdio(0);    int n,m,loop = 0;    cin>>n>>m;    int root;    for(int i = 1;i <= m; i++)    {        int x,y;        scanf("%d%d",&x,&y);        a[i].u=x;a[i].v=y;        if (x != y)        {            G[x].push_back(y);            G[y].push_back(x);        }else loop++;        inq[x]++; inq[y]++;        root = x;    }    dfs(root);    for(int i = 1;i <= n;i++)        if(!vis[i]&&inq[i]!=0)        {            puts("0");            return 0;        }    ll ans = 0;    for(int i = 1; i <= m; i++)    {        int x = a[i].u;        int y = a[i].v;        if (x!=y) ans += G[x].size()-1+G[y].size()-1+loop;        else ans += m-1;    }    cout<<ans/2<<endl;    return 0;}
0 0
原创粉丝点击