爬山游记
爬啊爬
我爱大自然(雾
JSOI2016 炸弹攻击
由于是随机坐标,且ans是整数变化不大,我们可以使用一半的模拟退火一半的爬山
#include<bits/stdc++.h>
#include<ctime>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N = 2001;
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ROF(i,a,b) for(int i=a;i>=b;--i)
int n,a[N],x[N],y[N],r[N],p[N],q[N],m;
double R,st;
int read(){
int x=0,pos=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return pos?x:-x;
}
const double eps= 1e-10;
double dis(double a,double b,double c,double d){
return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
double calc(int nx,int ny){
double nd=R;
FOR(i,1,n){
nd=min(nd,dis(nx,ny,x[i],y[i])-r[i]);
}
int res=0;
FOR(i,1,m){
if(dis(nx,ny,p[i],q[i])<nd+eps) res++;
}
return res;
}
double X,Y;
int SA(double nx,double ny){
double T=2000,t0=2000;double ans=calc(nx,ny);
while(T>eps){
// if(1000*(clock()-st)>=970*CLOCKS_PER_SEC) break;
double tx=nx+1.0*(rand()*2-RAND_MAX)*T;
double ty=ny+1.0*(rand()*2-RAND_MAX)*T;
double delta=calc(tx,ty)-ans;
if(delta>0){
ans+=delta,nx=tx,ny=ty;
}//else if(1.0*exp(delta/T)*RAND_MAX>1.0*rand()){
// ans+=delta,nx=tx,ny=ty;
// }
T*=0.998;
}
if(ans<0) return 0;
else return (int)(ans);
}
int main(){
srand(time(0));
n=read();m=read();R=read();st=clock();
double sx=0,sy=0;
FOR(i,1,n){
x[i]=read(),y[i]=read(),r[i]=read();
}
FOR(i,1,m){
p[i]=read(),q[i]=read();
sx=sx+p[i];sy=sy+q[i];
X=X+abs(p[i]);Y=Y+abs(q[i]);
}
sx/=m,sy/=m;
X/=m,Y/=m;
int ans=0;
while(1000*(clock()-st)<900*CLOCKS_PER_SEC){
ans=max(ans,SA(sx*rand()/RAND_MAX,sy*rand()/RAND_MAX));
}
printf("%d
",ans);
return 0;
}
WC2018 通道
乱搞,利用树的直径的思想(?)
74~87分
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,pos=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return pos?x:-x;
}
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
const int N = 1e5+200;
int n;
int R(int now){
return rand()%now+1;
}
struct graph{
#define pil pair<int,ll>
#define fi first
#define se second
vector<pil>G[N];
int fa[N],sz[N],dep[N],son[N],top[N],vis[N];ll val[N];/*
void dfs1(int now,int pre){
fa[now]=pre;dep[now]=dep[pre]+1;sz[now]=1;
for(int i=0;i<G[now].size();i++){
int v=G[now][i].fi;
if(v==pre) continue;
val[v]=G[now][i].se+val[now];
dfs1(v,now);
if(sz[v]>sz[son[now]]) son[now]=v;
}
}
void dfs2(int now,int tp){
top[now]=tp;
if(son[now]) dfs2(son[now],tp);
for(int i=0;i<G[now].size();i++){
int v=G[now][i].fi;
if(v==fa[now]||v==son[now]) continue;
dfs2(v,v);
}
}
int lca(int a,int b){
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]]) swap(a,b);
a=fa[top[a]];
}
if(dep[a]>dep[b]) swap(a,b);return a;
}
ll query(int a,int b){
return val[a]+val[b]-2*val[lca(a,b)];
}
int getnex(int now){
return G[now][R(G[now].size())-1].fi;
}*/
void dfs(int now,int pre){
for(int i=0;i<G[now].size();i++){
int v=G[now][i].fi;
if(v==pre) continue;
val[v]=G[now][i].se+val[now];
dfs(v,now);
if(sz[v]>sz[son[now]]) son[now]=v;
}
}
void init(){
FOR(i,1,n-1){
int u=read(),v=read();ll w;scanf("%lld",&w);
G[u].push_back(make_pair(v,w));
G[v].push_back(make_pair(u,w));
}
}
}g[3];
ll ans=0;
ll calc(int now){
return g[0].val[now]+g[1].val[now]+g[2].val[now];
}
ll getans(int u){
FOR(i,0,2){
FOR(j,1,n) g[i].val[j]=0;
g[i].dfs(u,0);
}
ll an=0;int res=0;
FOR(i,1,n){
if(i==u) continue;
if(calc(i)>an){
res=i,an=calc(i);
}
}
ans=max(ans,an);
return res;
}
const double eps = 1e-9;
void SA(){
int s=R(n),t;
FOR(i,1,10){
t=getans(s);swap(s,t);
}
}
int main(){
srand(time(0));
n=read();
g[0].init();g[1].init();g[2].init();
FOR(i,1,13) SA();
printf("%lld
",ans);
return 0;
}