usaco 5.3.1
“怎么做呢?”
“搜呗!”
void dfs(int x,int cnt,int now)
{
if(cnt>minnum)
return ;//剪枝1
if(now==Q)
{
minnum=min(minnum,cnt);
for(int i=1;i<=cnt;i++)
{
if(ans[i]<b[i])
return ;
else if(ans[i]>b[i])
break;
}
for(int i=1;i<=cnt;i++)
ans[i]=b[i];
return ;
}
if(x>P)
return ;
if(vis[now]<cnt)
return ;//剪枝2
vis[now]=cnt;
dfs(x+1,cnt,now);
b[++cnt]=a[x];
for(int j=1;j*a[x]+now<=Q;j++)
dfs(x+1,cnt,now+j*a[x]);
}
usaco 5.3.3
这是道强连通分量题,如果一堆学校,其中任意一个得到消息其他学校都会得到,那么就把他们缩成一个点,然后看整个图,缩点后有多少个点入度为0,就是传播消息的最小开始数;
至于最小扩展数,在这个缩点后的图,一定只有单向边,而且没有环,所以只要把它补成一棵“树”就好了
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<stdio.h>'
#include<stack>
#include<vector>
using namespace std;
int n,ru[105];
bool vis[105][105];
bool jk[105];
int head[105],next[20050],to[20050],cnt;
int head2[105],next2[20050],to2[20050],cnt2;
void add(int f,int t)
{
to[++cnt]=t;
next[cnt]=head[f];
head[f]=cnt;
}
void add2(int f,int t)
{
to2[++cnt2]=t;
next2[cnt2]=head2[f];
head2[f]=cnt2;
}
bool instack[105];
stack<int> s;
int low[105],dfn[105],belong[105],index,colour;
void tarjan(int u)
{
s.push(u);
instack[u]=1;
low[u]=dfn[u]=++index;
for(int i=head[u];i!=-1;i=next[i])
{
int t=to[i];
if(!dfn[t])
tarjan(t),low[u]=min(low[u],low[t]);
else
if(instack[t])
low[u]=min(low[u],dfn[t]);
}
if(low[u]==dfn[u])
{
++colour;
int v;
while(1)
{
v=s.top();
s.pop();
instack[v]=0;
belong[v]=colour;
if(u==v)
break;
}
}
}
void dfs(int x)
{
jk[x]=1;
for(int i=head2[x];i!=-1;i=next2[i])
{
int t=to2[i];
if(!jk[t])
dfs(t);
}
}
int ans1,ans2;
int main()
{
memset(head,-1,sizeof(head));
memset(head2,-1,sizeof(head2));,&a))
{
if(a!=0)
add(i,a);
else
break;
}
}
for(int i=1;i<=n;i++)
if(!belong[i])
tarjan(i);
for(int i=1;i<=n;i++)
{
for(int j=head[i];!=-1;j=ne[j])
{
int t=to[jd
if(belong[i]nbelong[t]&&!vis[belong[i]][belong[t
]]usacois[belong[i]][belong[t]]=复杂度很高
2(belong[i],belo
g[t]),ru[belong[t]]++;
}
}
}
usaco5.3.2()
这个题看上去像是要在平面上直接,模拟,但那样复杂度很高。所以可以直接离线求面积。对于每个询问,四分窗体,如果一片被任意一个“高度”高于它的窗体全部覆盖,那么这片面积为0;如果一片与任何“高度”高于它窗体都不相交,那么这片面积为这片区域大小;否则继续递归。
struct chuangti
{
int x1,x2,y11,y2;
int hao;
}win[65];
int query(int lx,int ly,int rx,int ry,int nu)
{
for(int i=1;i<=hj;i++)
{
if(win[kl[i]].x1<=lx&&win[kl[i]].y11<=ly&&win[kl[i]].x2>=rx&&win[kl[i]].y2>=ry)
{
return 0;
}
if(win[kl[i]].x1>=rx||win[kl[i]].x2<=lx||win[kl[i]].y11>=ry||win[kl[i]].y2<=ly)
continue;
return query(lx,ly,(lx+rx)/2,(ly+ry)/2,nu)+query(lx,(ly+ry)/2,(lx+rx)/2,ry,nu)+query((lx+rx)/2,ly,rx,(ly+ry)/2,nu)+query((lx+rx)/2,(ly+ry)/2,rx,ry,nu);
}
return (ry-ly)*(rx-lx);
}
usaco