• Joining Byte Blocks(哈希+带花树)


    题目链接

    Problem Statement

    As you are probably aware, the Internet protocols specify a canonical byte order convention for data transmitted over the network called network byte order, so that machines with different byte order conventions can communicate. But what if such canonical byte order didn't exist? We would probably be trapped in chaos trying to figure out the byte order for every machine we want to communicate with. But luckily, no matter the byte order (big-endian or little-endian), there will be byte blocks that will always be read correctly. 

    Imagine you have a list of N byte blocks. In order to minimize the number of trasmission operations required to send all of them, you want to pair as many as possible blocks. Note that the resulting byte frame should have same representation in both network orders, i.e., they should be a palindrome when paired. The rules for such pairings are the following:

    • No block can be paired with itself.
    • A block can be paired zero or one time.
    • You cannot pair more than two blocks.

    For the ease of representation we will use lowercase latin characters to represent byte blocks. Suppose we have two blocks [a,a,f] and [f], and they are paired to form the frame [f,a,a,f], then it has the same representation in any of the byte order. 

    Now, given the list of blocks, using the pairings described above, what's the minimum number of transmissions required to send them all?

    Note: A block can either be transmitted alone, or paired with another block (if the pair satisfies above criteria).

    Input Format

    There will be multiple test cases per input file. Every test case will start with a number Ntelling you the size of the list. Then N lines follow, each one with a block, where each byte has been replaced by its current English alphabet lowercase letter. No test case will have more than 3000 potential pairs.

    Output Format

    Output a single line per test case in the input with the required answer.

    Constraints

    • 1number of test cases6
    • 1N1000
    • 1length of each block1000
    • Each block consisits of lowercase latin characters, [a,z].

    Sample Input

    6
    aaababa
    aa
    ababaaa
    baaa
    a
    b
    9
    aabbaabb 
    bbaabbaa
    aa
    bb
    a
    bbaa
    bba
    bab
    ab
    

    Sample Output

    3
    5
    

    Explanation

    • Sample Case #00: All of the blocks can be paired into following 3 frames.

      • "baaa" + "b" = "baaab"
      • "aaababa + "ababaaa" = "aaababaababaaa"
      • "aa" + "a" = "aaa"
    • Sample Case #01: Following frames will be sent

      • "aabbaabb" + "bbaabbaa" = "aabbaabbbbaabbaa"
      • "aa" + "a = "aaa"
      • "bba" + "bb" = "bbabb"
      • "bab" + "ab" = "babab"
      • "bbaa"

    又一个之前没有用过的字符串hash的应用。还加了个一般图最大匹配的模板。

    AC代码:

      1 #include<set>
      2 #include<map>
      3 #include<cmath>
      4 #include<queue>
      5 #include<cstdio>
      6 #include<vector>
      7 #include<string>
      8 #include<cstdlib>
      9 #include<cstring>
     10 #include<iostream>
     11 #include<algorithm>
     12 using namespace std;
     13 
     14 #define mem(a, b) (memset(a, b, sizeof(a)))
     15 #define pb push_back
     16 #define all(v) v.begin(), v.end()
     17 #define rall(v) v.rbegin(), v.rend()
     18 #define rep(i, m) for (int i = 0; i < (int)(m); i++)
     19 #define rep2(i, n, m) for (int i = n; i < (int)(m); i++)
     20 typedef long long LL;
     21 typedef pair<LL, LL> PLL;
     22 
     23 const int oo = (int) 1e9;
     24 const double PI = 2 * acos(0);
     25 const double eps = 1e-9;
     26 const int MAX_N = 2048;
     27 
     28 const int P = 131;
     29 const int Q = 191;
     30 const int MP = 1000003;
     31 const int MQ = 10000019;
     32 LL pw[MAX_N], qw[MAX_N];
     33 char str[MAX_N];
     34 #define F first
     35 #define S second
     36 
     37 /* 采用两个hash函数*/
     38 struct strHash {
     39     PLL str, rev;
     40     int len;
     41 
     42     strHash operator +(const strHash &o) const {
     43         strHash res;
     44         res.str.F = (str.F * pw[o.len] + o.str.F) % MP;
     45         res.str.S = (str.S * qw[o.len] + o.str.S) % MQ;
     46         res.rev.F = (o.rev.F * pw[len] + rev.F) % MP;
     47         res.rev.S = (o.rev.S * qw[len] + rev.S) % MQ;
     48         res.len = len + o.len;
     49         return res;
     50     }
     51 }s[MAX_N];
     52 
     53 void init() {
     54     pw[0] = qw[0] = 1;
     55     for (int i = 1; i < MAX_N; i++) {
     56         pw[i] = pw[i-1] * P % MP;
     57         qw[i] = qw[i-1] * Q % MQ;
     58     }
     59 }
     60 
     61 strHash makeHash(const char *str) {
     62     strHash res;
     63     res.len = strlen(str);
     64     res.str.F = res.str.S = 0;
     65     for (int i = 0; i < res.len; i++) {
     66         res.str.F = (res.str.F * P + str[i]) % MP;
     67         res.str.S = (res.str.S * Q + str[i]) % MQ;
     68     }
     69     res.rev.F = res.rev.S = 0;
     70     for (int i = res.len-1; ~i; i--) {
     71         res.rev.F = (res.rev.F * P + str[i]) % MP;
     72         res.rev.S = (res.rev.S * Q + str[i]) % MQ;
     73     }
     74     return res;
     75 }
     76 
     77 /* 判断a+b 或者 b+a是否为回文 */
     78 inline bool check(const strHash &a, const strHash &b) {
     79     strHash u = a + b;
     80     if (u.str == u.rev) return true;
     81     strHash v = b + a;
     82     if (v.str == v.rev) return true;
     83     return false;
     84 }
     85 
     86 
     87 /* 一般图最大匹配(带花树) */
     88 const int MAX = 2048;
     89 struct GraphMatch {
     90   int Next[MAX];
     91   int spouse[MAX];
     92   int belong[MAX];
     93 
     94   int findb(int a) {
     95     return belong[a]==a?a:belong[a]=findb(belong[a]);
     96   }
     97   void together(int a,int b){
     98     a=findb(a),b=findb(b);
     99     if (a!=b)belong[a]=b;
    100   }
    101 
    102   vector<int> E[MAX];
    103   int N;
    104   int Q[MAX],bot;
    105   int mark[MAX];
    106   int visited[MAX];
    107 
    108   int findLCA(int x,int y){
    109     static int t=0;
    110     t++;
    111     while (1) {
    112       if (x!=-1) {
    113               x = findb(x);
    114               if (visited[x]==t)return x;
    115               visited[x]=t;
    116               if (spouse[x]!=-1)x=Next[spouse[x]];
    117               else x=-1;
    118           }
    119           swap(x,y);
    120       }
    121   }
    122 
    123   void goup(int a,int p){
    124     while (a!=p){
    125           int b=spouse[a],c=Next[b];
    126           if (findb(c)!=p)Next[c]=b;
    127           if (mark[b]==2)mark[Q[bot++]=b]=1;
    128           if (mark[c]==2)mark[Q[bot++]=c]=1;
    129           together(a,b);
    130           together(b,c);
    131           a=c;
    132       }
    133   }
    134 
    135     void findaugment(int s){
    136       for (int i=0;i<N;i++) {
    137           Next[i]=-1;
    138           belong[i]=i;
    139           mark[i]=0;
    140           visited[i]=-1;
    141       }
    142       Q[0]=s;bot=1;mark[s]=1;
    143       for (int head=0;spouse[s]==-1 && head<bot;head++){
    144           int x=Q[head];
    145           for (int i=0;i<(int)E[x].size();i++){
    146                 int y=E[x][i];
    147                 if (spouse[x]!=y && findb(x)!=findb(y) && mark[y]!=2){
    148                     if (mark[y]==1){
    149                         int p=findLCA(x,y);
    150                         if (findb(x)!=p)Next[x]=y;
    151                         if (findb(y)!=p)Next[y]=x;
    152                         goup(x,p);
    153                         goup(y,p);
    154                     }else if (spouse[y]==-1){
    155                         Next[y]=x;
    156                         for (int j=y;j!=-1;){
    157                             int k=Next[j];
    158                             int l=spouse[k];
    159                             spouse[j]=k;spouse[k]=j;
    160                             j=l;
    161                         }
    162                         break;
    163                     }else{
    164                         Next[y]=x;
    165                         mark[Q[bot++]=spouse[y]]=1;
    166                         mark[y]=2;
    167                     }
    168                 }
    169             }
    170         }
    171     }
    172 
    173     void init(int n) {
    174       N = n;
    175       for (int i = 0; i < N; ++i) {
    176         E[i].clear();
    177       }
    178     }
    179 
    180     void addEdge(int a, int b) {
    181       E[a].push_back(b);
    182       E[b].push_back(a);
    183     }
    184 
    185     int maxMatch() {
    186       int ret = 0;
    187       for (int i = 0; i < N; ++i) spouse[i] = -1;
    188       for (int i = 0; i < N; ++i) {
    189         if (spouse[i] == -1) {
    190           findaugment(i);
    191         }
    192       }
    193       for (int i = 0; i < N; ++i) {
    194         if (spouse[i] != -1) ++ret;
    195       }
    196       return ret;
    197     }
    198 } match;
    199 
    200 
    201 int main(void) {
    202     init();
    203     int N;
    204     while (~scanf("%d", &N)) {
    205         for (int i = 0; i < N; i++) {
    206             scanf("%s", str);
    207             s[i] = makeHash(str);
    208         }
    209 
    210         match.init(N);
    211         for (int i = 0; i < N; i++) {
    212             for (int j = i+1; j < N; j++) {
    213                 if (check(s[i], s[j])) {
    214                     match.addEdge(i, j);
    215                 }
    216             }
    217         }
    218         int cnt = match.maxMatch();
    219         /*
    220          for (int i = 0; i < N; i++) {
    221              printf("%d %d
    ", i, match.spouse[i]);
    222          }
    223          */
    224         printf("%d
    ", N - cnt / 2);
    225     }
    226 
    227     return 0;
    228 }
    View Code
  • 相关阅读:
    媒体定律:马航失联客机取代昆明袭击
    讨论世界的意义是否存在
    神与信仰和人的意义
    读《人生哲思录》论“人”与“意义”
    如果人类世界灭亡 幸存者有多少资源
    stagewidth stage.width 区别
    flash的render延迟渲染
    【翻译】自定义 UIViewController Transitions
    [功能]点击ImageView进入页面,时间响应者链实现
    开学面试笔试总结
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/4425952.html
Copyright © 2020-2023  润新知