# [3.17校内训练赛]

hzwer出的bzoj训练赛。

A.[bzoj1823][jsoi2010]满汉全席

#include<iostream>
#include<cstdio>
#define MAXN 200
#define INF 2000000000
#include<queue>
#include<cstring>
using namespace std;
{
int  x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

bool inq[MAXN+5];
int dfn[MAXN+5],low[MAXN+5],cc,belong[MAXN+5],in[MAXN+5],col[MAXN+5];
struct edge{
int to,next;
}e[1000000];
char st[1000];

int get()
{
scanf("%s",st+1);int x=0;
for(int i=2;st[i];i++)
x=x*10+st[i]-'0';
if(st[1]=='m')x+=n;
return x;
}

void ins(int f,int t)
{
e[cnt].to=t;
}

void tarjan(int x)
{
q[++top]=x;dfn[x]=low[x]=++dn;inq[x]=1;
if(!dfn[e[i].to]){tarjan(e[i].to);low[x]=min(low[x],low[e[i].to]);}
else if(inq[e[i].to])low[x]=min(low[x],dfn[e[i].to]);
if(dfn[x]==low[x])
for(++cc;q[top+1]!=x;inq[q[top]]=0,belong[q[top--]]=cc);
}

int main()
{
while(t--)
{
memset(belong,0,sizeof(belong));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));
for(int i=1;i<=n;i++)cft[i]=i+n,cft[i+n]=i;
for(int i=1;i<=m;i++)
{
int x=get(),y=get();
ins(cft[x],y);ins(cft[y],x);
}
for(int i=1;i<=n<<1;i++)if(!dfn[i])tarjan(i);
int i;
if(i>n)puts("GOOD");
}
return 0;
}

B.[bzoj1822][jsoi2010]Frozen Nova冷冻波

n,m,k<=200

#include<iostream>
#include<cstdio>
#define INF 2000000000
#include<queue>
#include<cmath>
#include<cstring>
#define S 0
#define T 401
using namespace std;
{
int  x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

bool mp[T+5][T+5];
struct edge{
int to,next,w;
}e[1000000];
inline double sqr(double x){return x*x;}
struct POINT{double x,y,r,t;
POINT operator-(POINT a){return (POINT){a.x-x,a.y-y};}
double operator*(POINT a){return x*a.y-y*a.x;}
}s[T],t[T],w[T];
double dis(POINT x,POINT y){return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));}
double dot(POINT x,POINT y){return x.x*y.x+x.y*y.y;}

queue<int> qu;
bool used[T+5];

void ins(int f,int t,int w)
{
e[cnt].to=t;e[cnt].w=w;
}

void insw(int f,int t,int w){ins(f,t,w);ins(t,f,0);}

int dfs(int x,int f)
{
if(x==T)return f;
int use=0;
if(e[i].w&&q[e[i].to]==q[x]+1)
{
int w=dfs(e[i].to,min(f-use,e[i].w));
use+=w;e[i].w-=w;e[i^1].w+=w;
if(use==f)return f;
}
return use;
}

bool bfs()
{
memset(q,0,sizeof(q));q[S]=1;qu.push(S);
while(!qu.empty())
{
int u=qu.front();qu.pop();
if(e[i].w&&!q[e[i].to])
{
q[e[i].to]=q[u]+1;
qu.push(e[i].to);
}
}
return q[T]>0;
}

bool check(POINT x,POINT y,POINT z)
{
double d=fabs((z-x)*(y-x)),len=dis(x,y);
if((double)d/(double)len>z.r) return true;
if(dot(y-x,z-x)<0)return dis(x,z)>z.r;
else if(dot((x-y),(z-y))<0)return dis(y,z)>z.r;
return false;
}

void build(int x)
{
for(int i=1;i<=n;i++)insw(S,i,x/w[i].t+1);
for(int j=1;j<=m;j++)insw(j+n,T,1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(mp[i][j])
insw(i,j+n,1);
}

int solve()
{
int l,r,mid,ans=-1,i,j,sum;l=0,r=200000000;
while(l<=r)
{
mid=l+r>>1;sum=0;build(mid);
while(bfs())sum+=dfs(S,INF);
//cout<<mid<<" "<<sum<<"GGF"<<endl;
if(sum==m)ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}

int main()
{
for(int i=1;i<=n;i++)
for(int i=1;i<=m;i++)
for(int i=1;i<=k;i++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(dis(w[i],s[j])<=w[i].r)
{
bool yes=true;
for(int l=1;l<=k;l++)
{
if(!check(w[i],s[j],t[l])){yes=false;break;}
}
if(yes)mp[i][j]=1;
}
cout<<solve();
return 0;
}

C.[bzoj4008][hnoi2015]亚瑟王

ditoly大佬的题解：我们可以把问题抽象为一开始我有r条线位于点1，我可以选择删掉其中的任何一条线，使得其他线都往后走一格（就是这一轮发动它并停止了），或者不删掉，直接走，两者的概率不同。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
{
int  x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

double q[225];
double s[225];
double f[135][225],r[135][225],r2[135][225];
int n,m;
double ans=0;

int main()
{
while(T--)
{
memset(r,0,sizeof(r));memset(r2,0,sizeof(r2));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
r[j][i]=r[j-1][i]+(1-r[j-1][i])*q[i];
r2[m][0]=1;
for(int i=m;i>=0;i--)
for(int j=1;j<=n;j++)
r2[i][j]=r2[i+1][j-1]*r[i+1][j]+r2[i][j-1]*(1-r[i][j]);
for(int i=m;i>=0;i--)
for(int j=1;j<=n;j++)
f[i][j]=f[i+1][j-1]*r[i+1][j]+s[j]*r2[i+1][j-1]*r[i+1][j]+f[i][j-1]*(1-r[i][j]);
for(int i=0;i<=m;i++)ans+=f[i][n];
printf("%0.10lf\n",ans);
}
return 0;
}

D.[bzoj3144][hnoi2013]切糕

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define S 0
#define T 64001
#define INF 2000000000
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

int qu[T+5],top,tail;
int n,m,h,d,cnt=1;
const int dis[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct edge{
int to,next,w;
}e[T*100];

inline int num(int x,int y,int z){return z==0?S:(z-1)*n*m+(x-1)*m+y;}
inline void insw(int f,int t,int w){ins(f,t,w);ins(t,f,0);}

int dfs(int x,int f)
{
if(x==T)return f;
int used=0;
for(int i=cur[x];i;i=e[i].next)
if(e[i].w&&q[e[i].to]==q[x]+1)
{
int w=dfs(e[i].to,min(e[i].w,f-used));
used+=w;e[i].w-=w;e[i^1].w+=w;
if(e[i].w)cur[x]=i;
if(used==f)return used;
}
if(!used)q[x]=-1;
return used;
}

bool bfs()
{
memset(q,0,sizeof(q));q[S]=1;qu[top=1]=S;tail=0;
while(top!=tail)
{
int u=qu[++tail];
if(e[i].w&&!q[e[i].to])
{
q[e[i].to]=q[u]+1;
qu[++top]=e[i].to;
}
}
return q[T]>0;
}

int main()
{
for(int k=1;k<=h;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)insw(num(i,j,h),T,INF);
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)for(int k=d+1;k<=h;k++)
for(int l=0;l<4;l++)
{
int xx=i+dis[l][0],yy=j+dis[l][1];
if(xx<1||yy<1||xx>n||yy>m)continue;
insw(num(i,j,k),num(xx,yy,k-d),INF);
}
int ans=0;
while(bfs())
printf("%d\n",ans);
return 0;
}

E.[bzoj3573][hnoi2014]米特运输

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<map>
#define MAXN 500000
#define mod 998244353
#define ll long long
using namespace std;
{
int  x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

struct edge{
int to,next;
}e[2*MAXN+5];
map<ll,int> mp;

void dfs(int x,int fa)
{
f[x]=fa;
if(e[i].to!=fa)dfs(e[i].to,x),num[x]++;
}

void solve(int x,ll nn,int fa)
{
mp[(1LL*nn*s[x])%mod]++;
solve(e[i].to,nn*num[x]%mod,x);
}

int main()
{
for(int i=1;i<n;i++)
solve(1,1,0);int ans=0;
for(map<ll,int>::iterator it=mp.begin();it!=mp.end();++it)
ans=max(ans,it->second);
cout<<n-ans;
return 0;
}

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
02-04
02-14 1264
12-20
04-10 427
04-08 1277
04-13 140
04-13 438
04-11 611
04-13 747

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。