CodeForces

来源:互联网 发布:淘宝美工制作流程 编辑:程序博客网 时间:2024/06/07 00:10

这题一开始看到是懵逼的,百度了很多题解也是懵逼的,以为是一个很难得图论问题,因为我图论也只会一些模版.但是后来仔细看发现其实这题不需要什么图的基础,也是一个思维题.
题目描述,需要这样一种路线,但是他区分不同的路线,是根据那些路走了两遍,那些路走了一遍来的,而不是行走顺序,这一点首先要看清楚.
第二呢,注意到这种路线满足所有点都被经过的特点,所以这是欧拉通路的定义,如果不知道可以百度,很简单的.
所以现在就是一个计数问题,找到所有将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_pairtypedef 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;}
原创粉丝点击