HDU 5469 Antonidas(樹上的字串匹配/搜尋)

bigbigship發表於2015-09-29

題目連結:傳送門

題意:

給定一棵樹,每一個節點有一個字元,給定一個目標字串,判斷能否在這棵樹上找到一條路徑使得這條路徑組成的字串等於目標串。

分析:

搜尋+剪枝,首先預處理出以1為根這個節點離葉子節點的最大距離,然後根據目標串匹配剩下的長度與這個最大深度作比較作為剪枝的依據。

程式碼如下:

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e4+10;

int n,len;
char mood[maxn];
char str[maxn];

struct Graph{
    vector <int >vc[maxn];
    int height[maxn];
    bool vis[maxn];
    int par[maxn];
    void init(){
        for(int i=0;i<maxn;i++)
            vc[i].clear();
        memset(height,0,sizeof(height));
        memset(vis,0,sizeof(vis));
    }
    void add(int u,int v){
        vc[u].push_back(v);
        vc[v].push_back(u);
    }
    void get_height(int u){
        height[u]=1;
        vis[u]=1;
        for(int i=0;i<vc[u].size();i++){
            int v = vc[u][i];
            if(!vis[v]){
                get_height(v);
                par[v]=u;
                height[u] = max(height[u],height[v]+1);
            }
        }
    }
    bool find_str(int u,int id,int remain){
        vis[u]=1;
        if(id>len) return 1;
        if(height[u]>remain){
            for(int i=0;i<vc[u].size();i++){
                int v = vc[u][i];
                if(!vis[v]&&mood[v]==str[id]){
                    if(find_str(v,id+1,remain-1))
                        return 1;
                }
            }
        }
        else{
            if(!vis[par[u]]&&mood[par[u]]==str[id])
                return find_str(par[u],id+1,remain-1);
        }
        return 0;
    }
}G;

int main()
{
    int t,cas=1;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        G.init();
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            G.add(u,v);
        }
        scanf("%s",mood+1);
        scanf("%s",str+1);
        G.get_height(1);
        for(int i=1;i<=n;i++)
            cout<<i<<": "<<G.height[i]<<endl;
        len = strlen(str+1);
        int tag=1;
        printf("Case #%d: ",cas++);
        for(int i=1;i<=n;i++){
            if(mood[i]==str[1]){
                memset(G.vis,0,sizeof(G.vis));
                if(G.find_str(i,2,len-1)){
                    tag=0;
                    break;
                }
            }
        }
        if(tag) puts("Impossible");
        else puts("Find");
    }
    return 0;
}


相關文章