【noip2017】

noip2017

小凯的疑惑

看到了一个简单易懂的证明

(x)(xequiv ma(mod b)(0le m<b))(因为(mge b)的话可以表示为(ma=(m\%b)*a+lfloor m/b floor*b*a=(m\%b)a+(n+lfloor m/b floor)b)(0le m\%b< b)

(x=ma+nb) 显然(nge0)时一定能表示出来,所以(n=-1)(0le m<b-1)

所以最大值为((b-1)a-b=ab-a-b)

时间复杂度

我lxy就是死,从这里跳下去,也不会做这道恶熏熏的题的!

逛公园

先dij跑一遍最短路 然后再类似dp来计算有多少条

若当前(used[u][val]==1)说明这个点还未走完又被进入了,构成了一个(0)环 无解

int tot=0,head[N];
struct edge{int v,w,nxt;}e[M];
void add(int u,int v,int w){e[++tot]=(edge){v,w,head[u]},head[u]=tot;}

int dis[N];bool vis[N];
priority_queue<pii>q;
void clean(){memset(dis,inf,sizeof(dis)),memset(vis,0,sizeof(vis));}
void dij(int st){
	clean();
	q.push(make_pair(dis[st]=0,st));
	while(!q.empty()){
		int u=q.top().second;q.pop();
		if(vis[u]) continue;vis[u]=1;
		for(int i=head[u],v;i;i=e[i].nxt)
		if((i&1)&&dis[v=e[i].v]>dis[u]+e[i].w) q.push(make_pair(-(dis[v]=dis[u]+e[i].w),v));
	}
}

int f[N][55],used[N][55];
int dfs(int u,int val){
	if(used[u][val]==1||fl) return fl=1;
	if(used[u][val]==2) return f[u][val];
	used[u][val]=1;
	for(int i=head[u],v,w;i;i=e[i].nxt) if(!(i&1)){
		w=dis[u]+val-dis[v=e[i].v]-e[i].w;
		if(w>K||w<0) continue;
		f[u][val]+=dfs(v,w),f[u][val]%=P;
	}used[u][val]=2;
	return f[u][val];
}


int main(){
#ifndef ONLINE_JUDGE
    freopen("T1.txt","r",stdin);
#endif
	int T;rd(T);
	while(T--){
		memset(head,0,sizeof(head)),tot=ans=fl=0;
		memset(used,0,sizeof(used)),memset(f,0,sizeof(f));
		rd(n),rd(m),rd(K),rd(P);
		for(int i=1,u,v,w;i<=m;++i) rd(u),rd(v),rd(w),add(u,v,w),add(v,u,w);
		dij(1);f[1][0]=1;
		for(int i=0;i<=K&&!fl;++i) ans+=dfs(n,i),ans%=P;
		if(fl) puts("-1");
		else printf("%d
",ans);	
	}
    return 0;
}

奶酪

dfs?搜一下有没有一个在最底层的洞能延伸到最顶层

long long x[maxn],y[maxn],z[maxn];
int vis[maxn];
long long su(long long int x1,long long x2,long long y1,long long y2,long long z1,long long z2){
	long long wa=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2);
	return wa;
}
void dfs(int x1,int y1,int z1,int cnt){
	if(z1+r>=h) {fnd=1;return;}
	vis[cnt]=1;
	for(int i=1;i<=n;i++)
		if(!vis[i]&&su(x1,x[i],y1,y[i],z1,z[i])<=4*r*r) dfs(x[i],y[i],z[i],i);
}
int main(){
	scanf("%d",&t);
	for(int i=1;i<=t;i++){
		memset(vis,0,sizeof(vis));fnd=0;
		scanf("%d%d%lld",&n,&h,&r);
		for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&x[i],&y[i],&z[i]);
		for(int i=1;i<=n;i++)
			if(z[i]-r<=0) dfs(x[i],y[i],z[i],i);
		if(fnd) printf("Yes
");
		else printf("No
");
	}
	return 0;
}

宝藏

康代码把 枚举从哪个洞开始打

int cnt[N];
void dfs(int st){
	for(int i=1;i<=n;++i)
	if(st&(1<<(i-1))){
		for(int j=1,nw,ret;j<=n;++j)
		if(!(st&(1<<(j-1)))&&mp[i][j]!=inf)
			if(nw=st|(1<<(j-1)),f[nw]>f[st]+mp[i][j]*cnt[i])
				ret=cnt[j],f[nw]=f[st]+mp[i][j]*cnt[i],cnt[j]=cnt[i]+1,dfs(nw),cnt[j]=ret;
	}
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("T1.txt","r",stdin);
#endif
	rd(n),rd(m);
	memset(mp,inf,sizeof(mp));
	for(int i=1,u,v,w;i<=m;++i) rd(u),rd(v),rd(w),mp[u][v]=mp[v][u]=Min(mp[u][v],w);
	for(int i=1;i<=n;++i){
		memset(f,inf,sizeof(f)),f[1<<(i-1)]=0;
		memset(cnt,inf,sizeof(cnt)),cnt[i]=1;
		dfs(1<<(i-1)),ans=min(ans,f[(1<<n)-1]);
	}
	printf("%d",ans);
    return 0;
}

列队

原文地址:https://www.cnblogs.com/lxyyyy/p/11826003.html