Gitignore 2020 上海icpc区域赛

Gitignore 2020 上海icpc区域赛

题目大意:

给你n个可以删除的文件路径,m个不能删除的文件路径,问最后删去所有可以删除的文件路径的最短的次数是多少?

文件路径有五个限制:

  • 文件路径不为空,且最后一定是一个文件,即不能以/ 结尾
  • 目录不能以 / 开头
  • 文件名和目录不为空,即不能有连续的 /
  • 所有的文件路径一定互不相同
  • 一个目录中不会出现子目录和最后的文件名相同

题解:

这个画个图其实就很明白了,最后一定会是一棵树,但是这棵树因为文件名和目录名可能相同,所以不能直接用名字来建树,我使用的是以字典树的方式来建树,这样可以消除文件名和目录名可能相同的影响,建好树之后,问题就变成,一棵树最少删去多少个节点,使得最后树上的节点都是我们需要的。

代码还是有点难码,因为要这里会有两个映射,一个是字符串到数字,一个是数字到树节点的映射。

要注意区分!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e3+10;
typedef pair<int,int>pii;
map<pii,int>trie;
map<string,int>mp;
vector<int>G[maxn];
char s[maxn];
int now,tot,flag[maxn];
void init(){
    now = tot = 0;
    mp.clear(),trie.clear();
    for(int i=0;i<=1005;i++) flag[i] = false,G[i].clear();
}
void insert(int len){
    int u = 0;
    string str = "";
    for(int i=1;i<=len;i++){
        if(s[i]=='/'){
            if(!mp[str]) mp[str] = ++now;
            int v = mp[str];
            if(!trie[pii(u,v)]) trie[pii(u,v)] = ++tot,G[u].push_back(tot);
            u = trie[pii(u,v)],str = "";
        }
        else str += s[i];
    }
}
void update(int len){
    int u = 0;
    string str = "";
    for(int i=1;i<=len;i++){
        if(s[i]=='/'){
            int v = mp[str];
            if(!v||!trie[pii(u,v)]) return ;
            u = trie[pii(u,v)];
            str = "",flag[u] = true;
        }
        else str += s[i];
    }
}
int dfs(int u){
    int ans = 0;
    if(!flag[u]) return 1;
    for(int i=0;i<G[u].size();i++){
        int v = G[u][i];
//        printf("u = %d v = %d\n",u,v);
        ans+=dfs(v);
    }
    return ans;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        init();
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%s",s+1);
            int len = strlen(s+1);
            s[len+1] = '/',insert(len+1);
        }
        flag[0] = true;
        for(int i=1;i<=m;i++){
            scanf("%s",s+1);
            int len = strlen(s+1);
            s[len+1] = '/',update(len+1);
        }
        int ans = dfs(0);
        printf("%d\n",ans);
    }
    return 0;
}

posted @ 2021-01-18 11:13  EchoZQN  阅读(78)  评论(0编辑  收藏  举报