20140709 总结

Naive啊!一个2002 个20....

作为一个很蠢的人,testC写了一个很丑的并查集,过了两个点答案都是1的点(之前还以为是正解)...

更蠢的是,根本写不来testA和testB....

所以剩下的就等到“我的造化远不止如此”的时候再写吧...//没有拿到暑假的数学卷子,不知道是开心还是不开心... 

 -----------------------------------------------------------------------------

testC

输入文件: testC.in  输出文件:testC.out 时限:1000ms

 

问题描述:

N个点M条边的无向图,当然可以连通也可以不连通。现在你需要知道至少多少条边才可能使图连通,假设这个答案是T。现在你需要求出用T条边把这个图连通需要多少种方案?

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

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

 

输入描述:

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

 

输出描述:

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

 

样例输入:

4 1 1000000000
1 4

 

样例输出:

8

数据范围:

N<=100000

 

题解:

设图可以可以连接成k坨, 每坨有cj[i]个点,答案就是

cj[i]*n^(k-2)

 1 #define NOMBRE "testC"
 2 #include <vector>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int MAXN = 1e5+10;
 9 const int MAXE = 1000+10;
10 
11 int n, m, MOD, u, v;
12 bool vis[MAXN];
13 char InputC;
14 vector<int> cj;
15 
16 inline int NextInt(){
17     int ret = 0;
18     do InputC = getchar();
19     while (!(48<=InputC && InputC<=97));
20     do ret *= 10, ret += InputC-48, InputC = getchar();
21     while (48<=InputC && InputC<=97);
22     return ret;
23 }
24 
25 struct Father{
26     int f, n;
27 
28     Father(){
29         n = 1;
30     }
31 }father[MAXN];
32 
33 inline int Find(int x){
34     return x==father[x].f ? x : father[x].f = Find(father[x].f);
35 }
36 
37 inline void Combine(int x, int y){
38     int xf = Find(x), yf = Find(y);
39     if (xf==yf) return;
40     if (xf<yf) swap(xf, yf);
41     father[xf].f = yf, father[yf].n += father[xf].n;
42 } 
43 
44 int main(){
45     freopen(NOMBRE ".in", "r", stdin);
46     freopen(NOMBRE ".out", "w", stdout);
47 
48     memset(vis, false, sizeof(vis));
49 
50     n = NextInt(), m = NextInt(), MOD = NextInt();
51     for (register int i=1; i<=n; i++)
52         father[i].f = i;
53     for (register int i=0; i<m; i++)
54         u = NextInt(), v = NextInt(), Combine(u, v);
55 
56     for (register int i=1; i<=n; i++){
57         int x = Find(i);
58         if (!vis[x]) vis[x] = true, cj.push_back(father[x].n);
59     }
60 
61     int len = cj.size();
62     long long Pri = 1;
63     for (register int i=0; i<len; i++)
64         Pri = Pri*cj[i]%MOD;
65     for (register int i=0; i<len-2; i++)
66         Pri = Pri*n%MOD;
67     if (len<=1) Pri = 1;
68     printf("%I64d
", Pri);
69 }
原文地址:https://www.cnblogs.com/cjhahaha/p/3836710.html