成功获得成就:和出题人的std错法一样
codeforces1061E
根据子树之间的限制关系建边跑最大费用流即可。
没错就是这道题我跟标程错的一毛一样。
真·代码:
#include
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=2005,M=6e5+5,inf=0x3f3f3f3f;
int n,m,X,Y,s,t,cnt=-1,tot=0,first[N],dis[N],pred[N],pos[N],ans=0,w[N],lim[N],siz[N],A,B;
bool in[N];
vector<int>g[N][2],son[N];
struct edge{int v,c,next,w;}e[M<<1];
inline void add(int u,int v,int c,int w){
e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt,e[cnt].w=w,e[cnt].c=c;
e[++cnt].v=u,e[cnt].next=first[v],first[v]=cnt,e[cnt].w=-w,e[cnt].c=0;
}
inline bool spfa(){
queue<int>q;
for(ri i=s;i<=t;++i)pred[i]=-1,in[i]=0,dis[i]=-inf,pos[i]=-1;
dis[s]=0,in[s]=1,q.push(s);
while(!q.empty()){
int x=q.front();
q.pop(),in[x]=0;
for(ri i=first[x];~i;i=e[i].next){
int v=e[i].v;
if(e[i].c&&dis[v]<dis[x]+e[i].w){
dis[v]=dis[x]+e[i].w,pred[v]=x,pos[v]=i;
if(!in[v])in[v]=1,q.push(v);
}
}
}
if(dis[t]==-inf)return 0;
ans+=dis[t];
int p=t;
while(p^s)--e[pos[p]].c,++e[pos[p]^1].c,p=pred[p];
return 1;
}
void dfs(int p,int fa,int op){
son[p].push_back(p);
int tmp=0;
for(ri i=0,v;i<g[p][op].size();++i){
if((v=g[p][op][i])==fa)continue;
dfs(v,p,op),tmp+=siz[v];
for(ri j=0;j<son[v].size();++j)son[p].push_back(son[v][j]);
}
if(~lim[p]){
if(tmp>lim[p])puts("-1"),exit(0);
if(lim[p]>tmp){
int idx=++tot;
if(!op)add(s,idx,lim[p]-tmp,0);
else add(idx,t,lim[p]-tmp,0);
for(ri i=0;i<son[p].size();++i){
if(!op)add(idx,son[p][i],1,0);
else add(son[p][i]+n,idx,1,0);
}
}
son[p].clear();
}
siz[p]=~lim[p]?lim[p]:tmp;
}
inline void solve(int op){
for(ri i=1;i<=n;++i)son[i].clear(),lim[i]=-1,siz[i]=0;
int q=read();
for(ri i=1,x,v;i<=q;++i){
x=read(),v=read(),lim[x]=v;
if(x==X&&!op)A=v;
if(x==Y&&op)B=v;
}
dfs(op?Y:X,0,op);
}
int main(){
memset(first,-1,sizeof(first));
n=read(),s=0,tot=n*2,t=n*4+1,X=read(),Y=read();
for(ri i=1;i<=n;++i)w[i]=read(),add(i,i+n,1,w[i]);
for(ri i=1,u,v;i<n;++i)u=read(),v=read(),g[u][0].push_back(v),g[v][0].push_back(u);
for(ri i=1,u,v;i<n;++i)u=read(),v=read(),g[u][1].push_back(v),g[v][1].push_back(u);
solve(0),solve(1);
if(A^B)return puts("-1"),0;
while(spfa());
bool f=1;
for(ri i=first[s];~i;i=e[i].next)if(e[i].c)f=0;
for(ri i=first[t];~i;i=e[i].next)if(e[i^1].c)f=0;
if(!f)return puts("-1"),0;
else cout<<ans;
return 0;
}
codeforces1045H
跟这道题一毛一样
codeforces780H
考试的时候只想到了用均匀撒点水掉了 24 p t s 24pts 24pts
然而正解就是二分一下然后把所有的可形区域映射到 [ 0 , c m ] [0,\frac cm] [0,mc]上看有没有一个点被覆盖等于 m m m次。
嘴巴ac
O r z Orz Orz了一波其他神犇的代码:
#include
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return (ib==ob)?-1:*ib++;
}
inline int read(){
int ans=0;
bool f=1;
char ch=gc();
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return f?ans:-ans;
}
const int N=1e5+5;
const double eps=1e-9;
int n,m,num,cnt;
double len[N],sum=0,A,B,C;
inline double sqr(double x){return x*x;}
struct pot{
double x,y;
pot(double x=0,double y=0):x(x),y(y){}
friend inline pot operator+(const pot&a,const pot&b){return pot(a.x+b.x,a.y+b.y);}
friend inline pot operator-(const pot&a,const pot&b){return pot(a.x-b.x,a.y-b.y);}
friend inline pot operator*(const pot&a,const double&b){return pot(a.x*b,a.y*b);}
friend inline pot operator/(const pot&a,const double&b){return pot(a.x/b,a.y/b);}
inline double mod(){return sqr(x)+sqr(y);}
}a[N],dir[N],st,ed;
inline double dist(pot a,pot b){return sqrt((a-b).mod());}
struct F{double ql,qr,a,b,c;}f[N<<4];
struct Data{
double pos;
int v;
friend inline bool operator<(const Data&a,const Data&b){return fabs(a.pos-b.pos)<eps?a.v<b.v:a.pos<b.pos;}
}t[N<<4];
inline bool check(double lim){
cnt=0;
double l,r,z,x,y;
for(ri i=1;i<=num;++i){
A=f[i].a,B=f[i].b,C=f[i].c-lim;
l=f[i].ql,r=f[i].qr;
if(fabs(A)<eps){
if(fabs(B)<eps){if(C<eps)t[++cnt]=(Data){l,1},t[++cnt]=(Data){r,-1};}
else{
z=-C/B;
if(B>0&&z>0)t[++cnt]=(Data){l,1},t[++cnt]=(Data){min(l+z,r),-1};
else if(B<0&&l+z<r)t[++cnt]=(Data){max(l+z,0.0),1},t[++cnt]=(Data){r,-1};
}
}
else{
z=B*B-4*A*C;
if(z<0)continue;
z=sqrt(z),x=(-B-z)/(2*A),y=(-B+z)/(2*A);
if(l+x>r||y<0) continue;
t[++cnt]=(Data){l+max(0.0,x),1};
t[++cnt]=(Data){min(r,l+y),-1};
}
}
sort(t+1,t+cnt+1);
for(ri i=1,j=0;i<=cnt;++i){
j+=t[i].v;
if(j==m)return 1;
}
return 0;
}
int main(){
int pl=1,pr=1,id=1;
pot dr,dt;
double l=0,r,mid,res,cur=0,L,R,ave;
pot st,ed;
n=read(),m=read();
for(ri i=1;i<=n;++i)a[i].x=read(),a[i].y=read();
a[n+1]=a[1];
for(ri i=1;i<=n;++i){
len[i]=dist(a[i],a[i+1]);
dir[i]=(a[i+1]-a[i])/len[i];
sum+=len[i];
}
ave=R=sum/m;
for(;len[pr]<R+eps;++pr)R-=len[pr];
st=a[1],ed=a[pr]+dir[pr]*R;
L=len[1],R=len[pr]-R;
for(;cur+(1e-5)<sum;){
res=min(id*ave-cur,min(L,R));
dt=ed-st,dr=dir[pr]-dir[pl];
f[++num]=(F){cur-(id-1)*ave,cur-(id-1)*ave+res,dr.mod(),2*(dr.x*dt.x+dr.y*dt.y),dt.mod()};
cur+=res;
if(cur+(1e-5)>id*ave)id++;
st=st+(dir[pl]*res),ed=ed+(dir[pr]*res);
if(res+eps>L)pl=pl%n+1,L=len[pl];
else L-=res;
if(res+eps>R)pr=pr%n+1,R=len[pr];
else R-=res;
}
for(r=ave;r-l>eps;)mid=(l+r)/2.0,check(mid*mid)?r=mid:l=mid;
printf("%.8lf",l);
return 0;
}