zoukankan      html  css  js  c++  java
  • CF1207F Koala and Notebook(BFS)

    你可能会好奇为什么只有一个 BFS 的标签,却还能够排到 F 的位置。

    因为它实在是太 简 单 了

    有更新


    首先,比较两个数,可以先比较两个数的长度,然后比较两个数看成数字串后的字典序。

    不妨先把每条边拆成更多条边(中间加虚点),比如 233 拆成一条三条边的链,权分别是 2,3,3。

    对于长度,根据 BFS 的性质,肯定是长度短的先访问。所以接下来只用稍微注意一下字典序。

    其实也很简单:对每个出点,按照边权从小到大排序。可以证明访问到的点的答案(没取模)是单调不降的。

    有个小细节:对于一些答案相同的点在队列里面,可能有一个更优的转移是从后面的点转移得到的。然而对于大多数代码(也可能只是我的)是只会访问一次(就像普通 BFS 一样),就把前面不够优的转移选了。

    那么可以把答案相同的点一起处理,然后先枚举所有 0 边,再枚举所有 1 边……。

    如何判断两个点答案相同?直接比复杂度就挂了,答案是取模过的看起来也一副不能比的样子。

    然而……我不会了,所以我直接比了,然后就过了?

    求证明/hack……

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> PII;
    const int maxn=1337337,mod=1000000007;
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline int read(){
    	int x=0,f=0;char ch=getchar();
    	while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f?-x:x;
    }
    int n,m,cnt,h,r,q[maxn],ans[maxn];
    vector<int> e[maxn][10];
    bool vis[maxn],ch[maxn];
    int main(){
    	cnt=n=read();m=read();
    	FOR(i,1,m){
    		int u=read(),v=read();
    		int tmp=i,pre=v;
    		while(tmp>9){
    			e[++cnt][tmp%10].push_back(pre);
    			tmp/=10;pre=cnt;
    		}
    		e[u][tmp].push_back(pre);
    		tmp=i;pre=u;
    		while(tmp>9){
    			e[++cnt][tmp%10].push_back(pre);
    			tmp/=10;pre=cnt;
    		}
    		e[v][tmp].push_back(pre);
    	}
    	q[h=r=1]=1;
    	vis[1]=true;
    	ans[1]=0;
    	while(h<=r){
    		int L=h,R=0;
    		FOR(i,h+1,r) if(ch[q[i]]){R=i-1;break;}
    		if(!R) R=r;
    		FOR(j,0,9) FOR(i,L,R){
    			int u=q[i];
    			FOR(k,0,(int)e[u][j].size()-1){
    				int v=e[u][j][k];
    				if(vis[v]) continue;
    				vis[v]=true;
    				ans[v]=(10ll*ans[u]+j)%mod;
    				if(ans[q[r]]!=ans[v]) ch[v]=true;
    				q[++r]=v;
    			}
    		}
    		h=R+1;
    	}
    	FOR(i,2,n) printf("%d
    ",ans[i]);
    }
    

    upd:会真做法了。直接看代码,懒得说了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> PII;
    const int maxn=1337337,mod=1000000007;
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline int read(){
    	int x=0,f=0;char ch=getchar();
    	while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f?-x:x;
    }
    int n,m,cnt,h,r,q[maxn],ans[maxn];
    vector<int> e[maxn][10];
    bool vis[maxn],ch[maxn];
    int main(){
    	cnt=n=read();m=read();
    	FOR(i,1,m){
    		int u=read(),v=read();
    		int tmp=i,pre=v;
    		while(tmp>9){
    			e[++cnt][tmp%10].push_back(pre);
    			tmp/=10;pre=cnt;
    		}
    		e[u][tmp].push_back(pre);
    		tmp=i;pre=u;
    		while(tmp>9){
    			e[++cnt][tmp%10].push_back(pre);
    			tmp/=10;pre=cnt;
    		}
    		e[v][tmp].push_back(pre);
    	}
    	q[h=r=1]=1;
    	vis[1]=true;
    	ans[1]=0;
    	while(h<=r){
    		int L=h,R=0;
    		FOR(i,h+1,r) if(ch[q[i]]){R=i-1;break;}
    		if(!R) R=r;
    		FOR(j,0,9){
    			int hhh=0;
    			FOR(i,L,R){
    				int u=q[i];
    				FOR(k,0,(int)e[u][j].size()-1){
    					int v=e[u][j][k];
    					if(vis[v]) continue;
    					vis[v]=true;
    					ans[v]=(10ll*ans[u]+j)%mod;
    					if(++hhh!=1) ch[v]=true;
    					q[++r]=v;
    				}
    			}
    		}
    		h=R+1;
    	}
    	FOR(i,2,n) printf("%d
    ",ans[i]);
    }
    
  • 相关阅读:
    理想团队模式构建的设想以及对软件流程的理解
    一、环境搭建 之 Windows10 安装 python3.5.2
    Codeforces1176A(A题)Divide it!
    Codeforces1144A(A题)Diverse Strings
    Codeforces1144B(B题)Parity Alternated Deletions
    Codeforces1144C(C题)Two Shuffled Sequences
    Codeforces1144D(D题)Equalize Them All
    Codeforces1157A(A题)Reachable Numbers
    Codeforces1157B(B题)Long Number
    Codeforces1141E(E题)Superhero Battle
  • 原文地址:https://www.cnblogs.com/1000Suns/p/11559108.html
Copyright © 2011-2022 走看看