zoukankan      html  css  js  c++  java
  • HDU-1181 变形课(多种方式,好题)

            首先想到的是并查集,然后WA。。。原因在这,我第一次敲的是Find(1) == Find(12)来作为可以成功的条件,实际上这样是不行的,比方说 bell 和 mail实际上是不满足条件的,可以理解为有向边,合并的时候要注意是首尾相接,可以改为Find(1) == 12 或者 Find(12) == 1,具体取决于并查集父子节点的合并关系,其次可以使用弗洛伊德算法或者DFS都可以。

    并查集:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    const int N = 26 + 5;
    int pre[N];
    
    int Find(int x){
        return pre[x] == x? x : (pre[x] = Find(pre[x]));
    }
    
    void Merge(int x, int y){
        x = Find(x), y = Find(y);
        if(x != y) pre[x] = y; //这里要注意, 如果是pre[y] = x, 则要Find(12) == 1
    }
    char ch[N*10000];
    int main(){
        while(scanf("%s", ch) == 1){
            for(int i = 0; i < 26; i++) pre[i] = i;
            while(ch[0] != '0'){
                int x = ch[0] - 'a';
                int y = ch[strlen(ch) - 1] - 'a';
                Merge(x, y);
                scanf("%s", ch);
            }
            printf("%s
    ",Find(1) == 12?"Yes.":"No.");
        }
        return 0;
    }
    弗洛伊德:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    const int N = 26 + 5;
    const int INF = 0x3f3f3f3f;
    int mat[N][N];
    
    void Flory(){
        for(int k = 0; k < 26; k++)
            for(int i = 0; i < 26; i++)
                for(int j = 0; j < 26; j++)  mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]);
    }
    
    void Init(){
        for(int i = 0; i < 26; i++)
            for(int j = 0; j < 26; j++) mat[i][j] = (i!=j)?INF:0;
    }
    
    char ch[10010];
    int main(){
        while(scanf("%s", ch) == 1){
            Init();
            while(ch[0] != '0'){
                int x = ch[0] - 'a';
                int y = ch[strlen(ch)-1] - 'a';
                mat[x][y] = 1; //有向边
                scanf("%s", ch);
            }
            Flory();
            printf("%s.
    ",mat[1][12] < INF?"Yes":"No");
        }
        return 0;
    }
    DFS:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    const int N = 26 + 5;
    bool dp[N][N],can;
    
    void DFS(int x){
        if(can) return ;
        if(can = (x == 12)) return ;
        for(int i=0; i < 26; i++)
            if(dp[x][i]){
                dp[x][i] = false;
                DFS(i);
                dp[x][i] = true;
            }
    }
    void Init(){
        for(int i = 0; i < 26; i++)
            for(int j = 0; j < 26; j++) dp[i][j] = false;
        can = false;
    }
    char ch[10010];
    int main(){
        while(scanf("%s", ch) == 1){
            Init();
            while(ch[0] != '0'){
                int x = ch[0] - 'a';
                int y = ch[strlen(ch)-1] - 'a';
                dp[x][y] = true;
                scanf("%s", ch);
            }
            DFS( 1 );
            printf("%s.
    ", can?"Yes":"No");
        }
    }

  • 相关阅读:
    yolo_to_onnx ValueError: need more tan 1 value to unpack
    yolo_to_onnx killed
    C++ 实现二维矩阵的加减乘等运算
    Leetcode 1013. Partition Array Into Three Parts With Equal Sum
    Leetcode 1014. Best Sightseeing Pair
    Leetcode 121. Best Time to Buy and Sell Stock
    Leetcode 219. Contains Duplicate II
    Leetcode 890. Find and Replace Pattern
    Leetcode 965. Univalued Binary Tree
    Leetcode 700. Search in a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/Pretty9/p/7384039.html
Copyright © 2011-2022 走看看