zoukankan      html  css  js  c++  java
  • SPOJ LEXSTR 并查集

    题目描述:

    Taplu and Abhishar loved playing scrabble. One day they thought of inventing a new game using alphabet tiles. Abhishar wrote a string using tiles and gave a set of pairs (i,j) to Taplu.

    Pair “i, j” (0 based indexing) means that Taplu can swap the i’th and j’th tile in the string any number of times.  

    He then asks Taplu to give the lexicographically smallest string that can be produced by doing any number of swaps on the original string.

    Input

    First line contains T(1<=T<=10), the number of testcases.

    First line of each test case contains the initial string S. Length of Sttring is len(1<=len<=100000).

    Next line contains the number of pairs M (1<=M<=100000).

    Next M lines contains pairs i j that means ith character can be swapped with jth character.

    Note - i and j can be same and same i,j pair can occur twice.

     

    Output

    For each testcase output the lexicographically smallest string that can be made from the initial string.

    Example

    Input:

    1
    lmaf

    3
    0 1
    1 2
    2 3 Output: aflm

    题目的意思是给你一个字符串,然后给你n对位置,每一对位置上的两个字符可以进行无数次交换,问你进行足够多的交换后,你能得到的最小字典序的字符串是什么?

    如果想到并查集的话,就是把这n对位置进行集合上的合并,然后就变成了几个集合,这几个集合里面存的是一堆位置,在同一集合的位置能互换。
    现在我们只要每个集合中位置所对应的字符按照字典序排个序,每个集合都满足字典序最小,这样整体拼起来就也应该是最小的字典序。

    代码如下:
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 const int maxn =100800;
     5 vector<char> e[maxn];
     6 char s[maxn];
     7 int h[maxn];
     8 int father[maxn],l;
     9 int t,n;
    10 int Find(int x)
    11 {
    12     if (father[x]==x)
    13         return x;
    14     return father[x]=Find(father[x]);
    15 }
    16 void Union (int x,int y)
    17 {
    18     int fx=Find(x),fy=Find(y);
    19     if (fx!=fy);
    20     father[fx]=fy;
    21 }
    22 void init()
    23 {
    24     for (int i=0;i<maxn;++i)
    25         e[i].clear();
    26     memset(h,0,sizeof h);
    27     for (int i=0;i<maxn;++i)
    28         father[i]=i;
    29 }
    30 int main()
    31 {
    32     //freopen("de.txt","r",stdin);
    33     scanf("%d",&t);
    34     while (t--){
    35         init();
    36         scanf("%s",s+1);
    37         l=strlen(s+1);
    38         scanf("%d",&n);
    39         for (int i=0;i<n;++i){
    40             int a,b;
    41             scanf("%d%d",&a,&b);
    42             Union(++a,++b);
    43         }
    44         for (int i=1;i<=l;++i)
    45             e[Find(i)].push_back(s[i]);//将对应位置的字符加入vector,以便排序
    46         for (int i=1;i<=l;++i)
    47             sort(e[i].begin(),e[i].end());//将每个集合中的字母排序
    48         for (int i=1;i<=l;++i){
    49             int tmp=Find(i);//找到当前位置所在集合的代表元素
    50             printf("%c",e[tmp][h[tmp]++]);//输出当前集合的h[tmp]++个元素,h[]数组用于统计集合内已经输出了几个元素
    51         }
    52         printf("
    ");
    53     }
    54     return 0;
    55 }


  • 相关阅读:
    HDU-1275-两车追及或相遇问题(数学题目)
    hdu 2209 翻纸牌游戏
    HDU1217:Arbitrage(SPFA)
    HDU1548:A strange lift(Dijkstra或BFS)
    Hdu-2112 HDU Today (单源多点最短路——Dijsktra算法)
    HDU 3374 String Problem (KMP+最大最小表示)
    mysql导入的时候提示“1046-No Database selected”的解决办法
    win10开发环境下安装mongodb
    微服务项目开发学成在线_day01_CMS服务端开发
    springboot的http监控接口启动器的配置
  • 原文地址:https://www.cnblogs.com/agenthtb/p/6500525.html
Copyright © 2011-2022 走看看