//目录

ACM Arabella Collegiate Programming Contest 2015 F. Palindrome 并查集

题目链接:http://codeforces.com/gym/100676/attachments

题意: 

给一个字符串,有一些约束条件,两个位置要相同,有一些是问号,求最后有多少种方案回文?

 

分析:

每一个节点是一个集合,要是不同,有一个是问号,那么这个问号就是确定的(约束条件中,和回文的对称位置),单独的集合,他又是问号,就可以放26个字母了;

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 const int MAXN = 50005;
 8 
 9 char s[MAXN];
10 int n,m;
11 int f[MAXN],flag;
12 
13 int Find(int x)
14 {
15     if(x == f[x])
16         return x;
17     else return f[x] = Find(f[x]);
18 }
19 
20 void judge(int x,int y)
21 {
22     if(s[x] == s[y])
23         f[x] = y;
24     else if(s[x] == '?')
25         f[x] = y;
26     else if(s[y] == '?')
27         f[y] = x;
28     else flag = true;
29 }
30 
31 int main()
32 {
33     //freopen("in.txt","r",stdin);
34     int ncase;
35     scanf("%d",&ncase);
36     while(ncase--) {
37         flag = false;
38         scanf("%d%d%s",&n,&m,s);
39         for(int i = 0;i < n; i++)
40             f[i] = i;
41         for(int i = 0,j = n-1;i < j; i++,j--) {
42             judge(i,j);
43         }
44         for(int i = 0;i < m; i++) {
45             int a,b;
46             scanf("%d%d",&a,&b);
47             a--,b--;
48             judge(Find(a),Find(b));
49         }
50         if(flag) {
51             printf("0\n");
52             continue;
53         }
54         else {
55             long long ans = 1;
56             for(int i = 0;i < n; i++) {
57                 if(f[i] == i && s[i] == '?') {
58                     ans *= 26;
59                     ans %= 1000000007;
60                 }
61             }
62             printf("%lld\n",ans);
63         }
64     }
65     return 0;
66 }
View Code

 

posted @ 2017-04-21 21:21  小草的大树梦  阅读(253)  评论(0编辑  收藏  举报