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,就可以看出来。

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

    改:无

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

  • 相关阅读:
    wm
    usual
    itk_option remove
    Label Options
    imosflm controller
    set font
    namespace code
    git 之五分钟教程
    git 之五分钟教程
    学习perl正则表达式
  • 原文地址:https://www.cnblogs.com/rubylan/p/3837528.html
Copyright © 2011-2022 走看看