HDU6223 Infinite Fraction Path bfs+剪枝

Infinite Fraction Path

这个题第一次看见的时候,题意没搞懂就没做,这第二次也不会呀。。

题意:第i个城市到第(i*i+1)%n个城市,每个城市有个权值,从一个城市出发走N个城市,就可以得到一个长度为N的权值序列,求字典序最大的序列。

首先因为每个城市的出度为1,所以从任意城市出发都可以走出N步,通过打表可以发现度数为0的点几乎占了10分之9,也就是说大部分都是相同重复的部分。

虽然经过了一系列分析,但这并没有任何用,写了一发暴力dfs,T了。然后题解做题法,有几个解法,一个是鲲鲲有想到,但是卡常,我也不会。然后第二个就是bfs+剪枝。

有想到是搜索+剪枝,但一直想是怎么dfs记忆化,唉,太菜了。然后bfs很好理解,我们就按照深度的优先级一层层向下走,然后第一个剪枝就是,当前层已经保存的答案要是大于目前这个位置的权值,

那么很明显当前这个位置没必要扩展下去了,然后如果这个位置已经到过比现在更深的深度,那么有当前深度当那个深度之间的答案,已经被更新过了,那也没必要扩展了。

 1 #include<cstdio>
 2 #include<queue>
 3 using namespace std;
 4 const int N=2e5+11;
 5 char mp[N];
 6 int n,maxv,ne[N],dep[N],val[N],ans[N];
 7 struct Node{
 8     int pos,dep;
 9     Node(){}
10     Node(int pos,int dep):pos(pos),dep(dep){}
11     bool operator<(const Node &n1)const{
12         return dep==n1.dep ? val[pos]<val[n1.pos] : dep>n1.dep;
13     }
14 }qn;
15 void init(){
16     maxv=0;
17     for(int i=0;i<=n;i++){
18         dep[i]=ans[i]=-1;
19         val[i]=mp[i]-'0';
20         maxv=max(maxv,val[i]);
21         ne[i]=(1ll*i*i+1)%n;
22     }
23 }
24 void bfs(){
25     priority_queue<Node> q;
26     for(int i=0;i<n;i++) 
27         if(val[i]==maxv) q.push(Node(i,0));
28     while(!q.empty()){
29         qn=q.top();
30         q.pop();
31         if(ans[qn.dep]==-1) ans[qn.dep]=val[qn.pos];
32         else if(ans[qn.dep]>val[qn.pos]) continue;
33         if(dep[qn.pos]<qn.dep) dep[qn.pos]=qn.dep;
34         else continue;
35         if(qn.dep==n-1) continue; 
36         q.push(Node(ne[qn.pos],qn.dep+1)); 
37     }
38 }
39 int main(){
40     int t=1,T;
41     scanf("%d",&T);
42     while(t<=T){
43         scanf("%d",&n);
44         scanf("%s",mp);
45         init();
46         bfs();
47         printf("Case #%d: ",t++);
48         for(int i=0;i<n;i++) printf("%d",ans[i]);
49         printf("\n");
50     }
51     return 0;
52 }
搜索呀

 

posted @ 2019-10-07 16:47  新之守护者  阅读(224)  评论(0编辑  收藏  举报