• PKU_campus_2018_D Chocolate


    思路:

    题目链接http://poj.openjudge.cn/practice/C18D/

    kruskal过程中使用乘法原理计数。

    实现:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int MAXN = 405, INF = 0x3f3f3f3f;
     5 const ll MOD = 1e9 + 7;
     6 string s[MAXN];
     7 int d[MAXN][MAXN];
     8 int par[MAXN]; 
     9 ll num[MAXN];
    10 struct edge
    11 {
    12     int a, b, l;
    13 };
    14 edge es[MAXN * MAXN];
    15 void init(int n)
    16 {
    17     for (int i = 0; i < n; i++) { par[i] = i; num[i] = 1; }
    18 }
    19 int find(int x)
    20 {
    21     if (par[x] == x) return x;
    22     return par[x] = find(par[x]);
    23 }
    24 int uni(int x, int y)
    25 {
    26     x = find(x); y = find(y);
    27     if (x == y) return x;
    28     par[x] = y; return y;
    29 }
    30 int edit_dis(string a, string b)
    31 {
    32     int la = a.length(), lb = b.length();
    33     for (int i = 0; i <= la; i++) d[i][0] = i;
    34     for (int i = 0; i <= lb; i++) d[0][i] = i;
    35     for (int i = 1; i <= la; i++)
    36     {
    37         for (int j = 1; j <= lb; j++)
    38         {
    39             if (a[i - 1] == b[j - 1]) d[i][j] = d[i - 1][j - 1];
    40             else d[i][j] = min(d[i][j - 1], d[i - 1][j]) + 1;
    41         }
    42     }
    43     return d[la][lb];
    44 }
    45 bool cmp(edge & x, edge & y)
    46 {
    47     return x.l < y.l;
    48 }
    49 bool check(int x, int cnt)
    50 {
    51     int minn = INF, maxn = -INF;
    52     for (int i = 0; i < cnt; i++)
    53     {
    54         int px = find(es[i].a), py = find(es[i].b);
    55         if (px == x && py == x) maxn = max(maxn, es[i].l);
    56         else if ((px == x && py != x) || (px != x && py == x))
    57             minn = min(minn, es[i].l);
    58     }
    59     return maxn < minn;
    60 }
    61 int main()
    62 {
    63     int t, n;
    64     cin >> t;
    65     while (t--)
    66     {
    67         cin >> n;
    68         init(n);
    69         for (int i = 0; i < n; i++) cin >> s[i];
    70         int cnt = 0;
    71         for (int i = 0; i < n; i++)
    72         {
    73             for (int j = i + 1; j < n; j++)
    74             {
    75                 es[cnt].a = i; es[cnt].b = j; es[cnt].l = edit_dis(s[i], s[j]);
    76                 cnt++;
    77             }
    78         }
    79         sort(es, es + cnt, cmp);
    80         ll ans = 0; int tot = n;
    81         for (int i = 0; i < cnt; i++)
    82         {
    83             int px = find(es[i].a), py = find(es[i].b);
    84             if (px == py) continue;
    85             int tmp = uni(es[i].a, es[i].b);
    86             num[tmp] = num[px] * num[py] % MOD;
    87             if (check(tmp, cnt)) num[tmp] = (num[tmp] + 1) % MOD;
    88             tot--;
    89             if (tot == 1) ans = num[tmp];
    90         }
    91         cout << ans << endl;
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    javascript创建对象的方法--基本模式
    javascript进阶课程--第二章--对象
    JavaScript中的global对象,window对象以及document对象的区别和联系
    onblur 对象失去焦点事件
    php排序
    php数组插入数据
    thinkphp多层volist实现多表查询
    数据转换
    循环赛日程安排问题
    JS中setTimeout()的使用方法具体解释
  • 原文地址:https://www.cnblogs.com/wangyiming/p/9155409.html
Copyright © 2020-2023  润新知