zoukankan      html  css  js  c++  java
  • three

    79

    testC

    总时间限制:

    10000ms

    内存限制:

    128000kB

    描述

    N个点M条边的无向图,当然可以连通也可以不连通。

    现在你需要知道多少条边才可能使图连通,假设这个答案是T。

    现在你需要求出用T条边把这个图连通需要多少种方案?

     

    两种方案X和Y不同的定义为:其中至少有一条在X中的边不存在于Y中。

    输出这个答案模K的结果。

     

     

    输入

    第一行三个数N,M,K分别表示点数,边数,模数。

    输出

    一行一个数,表示最后答案模K的结果。

    样例输入

    4 1 1000000000

    1 4

    样例输出

    8

    提示

    数据范围:N,M<=10^5

     

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define PROC "testC"
    using namespace std;
    const int MAXN = 100005;  
    int fa[MAXN],ne;
    struct Edge
    {
    int to;
    Edge * next;
    } e[MAXN *2],*head[MAXN];
    bool b[MAXN];
    int ngroup = 0;
    int g[MAXN];
    int k ;
    long long pow(int p,int q)
    {
    long long ans = 1,t = p;
    while (q)
    {
      if (q & 1)
       ans *=t % k;
      t*=t %k;
      q>>=1;
    }
    return ans % k;
    }
    void addedge(int f,int to)
    {
    e[++ne].to = to;
    e[ne].next = head[f];
    head[f] = e+ne;
    return;
    }
    void findg(int now)
    {
    for (Edge * p = head[now];p;p=p->next)
    {
      if (!b[p->to])
      {  
       b[p->to] = true;
       g[ngroup]++;
       findg(p->to);
      }
    }
        return;
    }
    int main()
    {
    // freopen("test3.in.cpp","r",stdin);
    // freopen("testC.out","w",stdout);
    int n,m;
    scanf("%d%d%d",&n,&m,&k);
    int f,to;
    for (int i = 0;i<m;i++)
    {
      scanf("%d%d",&f,&to);
      addedge(f,to);
      addedge(to,f);
    }

    for (int i = 1;i<=n;i++)
        {
      if (!b[i])
      {   b[i] = true;
       g[++ngroup] = 1;
       findg(i);
      }
        }
        long long ans = 1;
        /*for (int i = 1;i<ngroup;i++)
         for (int j =i+1;j<=ngroup;j++)
            ans =(ans + sum%(g[i]*g[j]*k)/(g[i]*g[j]))%k;*/
        for (int i = 1;i<=ngroup;i++)
         ans =ans * g[i] % k;
        if (ngroup==1) ans  =1;
        else
        for (int i = 1;i<=ngroup-2;i++)
         ans =ans * n %k;
        // cout<<ngroup<<endl;
      //  ans  = ( (ans % k) * (pow(n,ngroup-2))) % k;
    cout<<ans%k;
    return 0;
    }

    错因:

    1. 1.       未完待续
    2. 2.       未完待续
    3. 3.       正解:连通块个数讨论,找出规律,正确的推导过程不是很明了。大概到n=4,就可以看出来。

    做:计算方案数时出现了遗漏

    改:无

    得:要正确认识自己设定的变量含义找规律要认真

  • 相关阅读:
    HDU 5486 Difference of Clustering 图论
    HDU 5481 Desiderium 动态规划
    hdu 5480 Conturbatio 线段树 单点更新,区间查询最小值
    HDU 5478 Can you find it 随机化 数学
    HDU 5477 A Sweet Journey 水题
    HDU 5476 Explore Track of Point 数学平几
    HDU 5475 An easy problem 线段树
    ZOJ 3829 Known Notation 贪心
    ZOJ 3827 Information Entropy 水题
    zoj 3823 Excavator Contest 构造
  • 原文地址:https://www.cnblogs.com/rubylan/p/3837528.html
Copyright © 2011-2022 走看看