期望得分:100+40+100=240

实际得分:100+40+100=240

 

2017 清北济南考前刷题Day 3 afternoon

将每个联通块的贡献乘起来就是答案

如果一个联通块的边数>点数 ,那么无解

如果边数=点数,那么贡献是 2

如果边数=点数-1,那么贡献是点数

#include<queue>
#include<cstdio>
#include<iostream>
 
using namespace std;

const int mod=1e9+7;

#define N 100001

int front[N],to[N<<1],nxt[N<<1],tot;

bool vis[N];

int d[N];

queue<int>q;

int ans=1;

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}

void add(int u,int v)
{
    to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
    to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
    d[v]++;
}

bool bfs(int s)
{
    while(!q.empty()) q.pop();
    int p=0,e=0;
    q.push(s); vis[s]=true;
    int now; 
    while(!q.empty())
    {
        now=q.front(); q.pop();
        p++; e+=d[now];
        for(int i=front[now];i;i=nxt[i])
            if(!vis[to[i]]) vis[to[i]]=true,q.push(to[i]);
    }
    if(e>p) return false;
    if(e==p) ans=ans*2%mod;
    else ans=1ll*ans*p%mod;
    return true;
}

int main()
{
    freopen("girl.in","r",stdin);
    freopen("girl.out","w",stdout);
    int n,m;
    read(n); read(m);
    int u,v;
    for(int i=1;i<=m;i++) 
    {
        read(u); read(v);
        add(u,v);
    }
    for(int i=1;i<=n;i++)
        if(!vis[i]) 
            if(!bfs(i)) { cout<<0; return 0; }
    cout<<ans;
    return 0;
}
View Code

相关文章:

  • 2022-02-24
  • 2021-10-27
  • 2022-01-10
  • 2021-11-13
  • 2022-01-29
  • 2021-11-05
  • 2021-06-26
  • 2021-10-12
猜你喜欢
  • 2022-01-24
  • 2021-07-13
  • 2021-11-09
  • 2022-02-20
  • 2021-09-23
  • 2021-11-11
  • 2021-10-03
相关资源
相似解决方案