首页 > 其他 > 详细

hdu 5469 Antonidas (dfs+剪枝)2015 ACM/ICPC Asia Regional Shanghai Online

时间:2015-09-29 23:32:43      阅读:350      评论:0      收藏:0      [点我收藏+]

题意:

给出一棵树,再给出每个节点上的值(一个char字符),然后给出一个s1字符串,问在这棵树上是否存在两个点,从一个点走到另一个点所经过的路径上的char字符组成的字符串正好等于s1。问是否存在这么两个点。如果存在,则输出“Find”,否则,输出“Important”。

 

题解:

使用dfs就可以解决,但是需要进行剪枝,否则就会tle

剪枝的方法是这样的——假设节点1是根节点,然后我们先使用一次dfs记录每个节点到叶节点的最长的路径dis[x]

然后开始搜索,每次搜到当前点xdis[x],如果dis[x]>剩下的字符串s1的值,那么可以走这条路,否则就不走这条路了,只向上看这个点的父节点是否满足。

 

具体见代码:

 

技术分享
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 const int N = 10010;
  8 
  9 struct Edge
 10 {
 11     int to, next;
 12 }edge[N<<1];
 13 
 14 int head[N], fm[N];
 15 int dis[N];
 16 bool vis[N];
 17 int n, t, k;
 18 int len;
 19 char s1[N], s2[N];
 20 
 21 void add(int u, int v)
 22 {
 23     edge[k].to = v;
 24     edge[k].next = head[u];
 25     head[u] = k++;
 26 }
 27 
 28 void tdfs(int x)
 29 {
 30     int mdis = -1;
 31     for(int i = head[x]; i != -1; i = edge[i].next)
 32     {
 33         int v = edge[i].to;
 34         if(!vis[v])
 35         {
 36             vis[v] = 1;
 37             tdfs(v);
 38             fm[v] = x;
 39             mdis = mdis > dis[v] ? mdis : dis[v];
 40         }
 41     }
 42     dis[x] = mdis == -1 ? 1 : mdis+1;
 43 }
 44 
 45 bool dfs(int x, int disx, int mlen)
 46 {
 47     if(disx-1 > len) return 1;
 48     if(dis[x] > mlen)
 49     {
 50         for(int i = head[x]; i != -1; i = edge[i].next)
 51         {
 52             int v = edge[i].to;
 53             if(!vis[v] && s1[v] == s2[disx])
 54             {
 55                 vis[v] = 1;
 56                 if(dfs(v, disx+1, mlen-1)) return 1;
 57             }
 58         }
 59     }
 60     else if(!vis[fm[x]] && s1[fm[x]] == s2[disx])
 61     {
 62         vis[fm[x]] = 1;
 63         return dfs(fm[x], disx+1, mlen-1);
 64     }
 65     return 0;
 66 }
 67 
 68 void init()
 69 {
 70     scanf("%d", &n);
 71     k = 0;
 72     memset(head, -1, sizeof(head));
 73     for(int i = 0; i < n; i++)
 74     {
 75         int a, b;
 76         scanf("%d%d", &a, &b);
 77         add(a, b);
 78         add(b, a);
 79     }
 80     memset(dis, 0, sizeof(dis));
 81     memset(vis, 0, sizeof(vis));
 82     tdfs(1);
 83     scanf("%s%s", s1+1, s2+1);
 84     len = strlen(s2+1)-1;
 85 }
 86 
 87 int main()
 88 {
 89     //freopen("test.in", "r", stdin);
 90     scanf("%d", &t);
 91     for(int tm = 1; tm <= t; tm++)
 92     {
 93         init();
 94         bool flag = 0;
 95         for(int i = 1; i <= n; i++)
 96         {
 97             if(s1[i] == s2[1])
 98             {
 99                 memset(vis, 0, sizeof(vis));
100                 if(dfs(i, 2, len))
101                 {
102                     flag = 1;
103                     break;
104                 }
105             }
106         }
107         printf("Case #%d: ", tm);
108         if(flag) printf("Find\n");
109         else printf("Impossible\n");
110     }
111 }
View Code

 

 

 

hdu 5469 Antonidas (dfs+剪枝)2015 ACM/ICPC Asia Regional Shanghai Online

原文:http://www.cnblogs.com/mypride/p/4847461.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!