zoukankan      html  css  js  c++  java
  • Codeforces 939D

    传送门:http://codeforces.com/contest/939/problem/D

    本题是一个数据结构问题——并查集(Disjoint Set)。

    给出两个长度相同,且仅由小写字母组成的字符串S=s[1..n]、T=t[1..n]。已知一个无序对(u,v)可以完成任意次的以下转换操作:u→vv→u。求将字符串S转换为T所需要的最少的无序对的数目,并打印出相应可行的方案下的所有无序对。

    首先构造一张无向图G=<V,E>,表示S→T的状态转换图:结点集V={‘a’,’b’,’c’,...,’z’};边集E={(si,ti)|si≠ti,i=1,2,...,n}。对于这张图的连通分量,构造一个边集最小的连通图——即无向图的生成树。可以采用简化的Kruskal算法求这棵生成树。

    实际上,这是一个并查集的问题。通过并查集,对于每一个i,判断siti是否在同一个集合中:若二者不在同一个集合中,则合并二者所在的集合。参考程序如下:

    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #define MAX_V 26
    #define MAX_N 100005
    
    char s[MAX_N], t[MAX_N];
    char uset[MAX_V], vset[MAX_V];
    
    //Disjoint Set
    int pa[MAX_V];
    int rank[MAX_V];
    
    void init(int n)
    {
        memset(pa, 0, sizeof(pa));
        memset(rank, 0, sizeof(rank));
        for (int i = 0; i < n; i++) {
            pa[i] = i;
            rank[i] = 0;
        }
    }
    
    int find(int x)
    {
        if (pa[x] == x) return x;
        else return pa[x] = find(pa[x]);
    }
    
    void unite(int x, int y)
    {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (rank[x] < rank[y]) pa[x] = y;
        else {
            pa[y] = x;
            if (rank[x] == rank[y]) rank[x]++;
        }
    }
    
    bool same(int x, int y)
    {
        return find(x) == find(y);
    }
    
    int main(void)
    {
        int n;
        scanf("%d", &n);
        scanf("%s", s);
        scanf("%s", t);
        int cnt = 0;
        init(MAX_V);
        for (int i = 0; i < n; i++) {
            if (s[i] != t[i]) {
                int u = s[i] - 'a';
                int v = t[i] - 'a';
                if (!same(u, v)) {
                    unite(u, v);
                    uset[cnt] = u + 'a';
                    vset[cnt] = v + 'a';
                    cnt++;
                }
            }
        }
        printf("%d
    ", cnt);
        for (int i = 0; i < cnt; i++)
            printf("%c %c
    ", uset[i], vset[i]);
        return 0;
    }
  • 相关阅读:
    C#高性能大容量SOCKET并发(转)
    使用 NuGet 更新套件時將 jQuery 升級到 2.0.2 應該如何降級
    《TD式创新”祸国殃民》
    技术负责人的三种角色
    WaitForSingleObject和CEvent用法
    C++和C#转换
    C#与C/C++的交互
    Introducing .NET Core
    NHibernate的调试技巧和Log4Net配置
    Using Windows Server 2012 Backup for Hyper-V Virtual Machines. Error 80780176
  • 原文地址:https://www.cnblogs.com/siuginhung/p/8452654.html
Copyright © 2011-2022 走看看