1006 Maex
题意
给你一个有根树,由编号从1到n的n个顶点组成,根是顶点1。 顶点i有一个自然数权重ai,没有两个不同的顶点具有相同的权重。bu=MEX { x ∣ ∃v∈subtree(u),x=av}。不幸的是,ai都不是给定的。请找出最大可能的∑(i=1)b。集合的MEX是不属于该集合的最小非负整数。
思路
本题采用树形dp。本题要求b数组的和的最大值,而b数组是以该结点为根的子树的权值中没有出现过的最小非负整数,要使它最大就应该使子树中尽可能出现更小的数,越小的数越应该出现在树叶部分,以使得层数越高的结点有越大的值,此时每个结点的b值等于该子树的结点个数。采用两个dfs,第一个dfs用来计算以各结点为根的子树的结点数目,第二个dfs用来计算最大权值之和。
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
int n;
const int N=500005;
int head[N],to[2*N],nxt[2*N];
int jd[N],du[N],qz[N];
int inf,cnt;
void add(int u,int v)
{
to[cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt++;
}
void dfs1(int u,int fa)//以该点为根的子树中包含的结点数目
{
jd[u]=1;
for(int i=head[u];i!=-1;i=nxt[i])
{
int j=to[i];
if(j==fa)
continue;
dfs1(j,u);
jd[u]+=jd[j];
}
}
void dfs2(int u,int fa)//一条链上所能获得的最大权值之和
{
if(fa==-1)
qz[u]=jd[u];
else
qz[u]=jd[u]+qz[fa];
if(du[u]==1)
{
inf=max(inf,qz[u]);
}
for(int i=head[u];i!=-1;i=nxt[i])
{
int j=to[i];
if(j==fa)
continue;
dfs2(j,u);
}
}
signed main()
{
IOS;
int t;
cin>>t;
int u,v;
int i,j;
while(t--)
{
cin>>n;
if(n==1)
{
cout<<"1\n";
continue;
}
for(i=0;i<=n;i++)
{
head[i]=-1;
du[i]=0;
qz[i]=0;
jd[i]=0;
}
inf=-0x3f3f3f3f;
cnt=0;
for(i=1;i<n;i++)
{
cin>>u>>v;
add(u,v);
add(v,u);
du[u]++;
du[v]++;
}
dfs1(1,-1);
dfs2(1,-1);
cout<<inf<<endl;
}
return 0;
}
1009 Map
题意
Sakuyalove有一个大的世界地图M和一个小的世界地图m,两个都是长方形的。小图m由大图M压缩而来,如果M的长度是a,M的宽度是b,那么m的长度是ka,m的宽度是kb,其中0<k<1。现在Sakuyalove把小地图m放到大地图M上,这样小地图就完全在大地图之内(包括边界)。她惊讶地发现,无论她如何放置小地图,总是恰好存在一个点P代表小地图和大地图中的相同位置。求P的位置坐标。
思路
本题采用巴拿赫不动点定理来计算定点。
通过求解二元一次方程组求得那两个变量,然后再将其带入第一个式子直接求得x和y。
通过这个式子可以直接求得那两个变量的值。
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int double
using namespace std;
struct node
{
int x,y;
};
node A,B,C,D,a,b,c,d;
signed main()
{
IOS;
int t;
cin>>t;
int i,j;
int ABx,ABy,abx,aby,ADx,ADy,adx,ady,Aax,Aay;
int aa,bb,cc,dd,ee,ff;
int x,y;
int xb,yb;
while(t--)
{
cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y
>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y;
aa=(B.x-A.x)-(b.x-a.x);
bb=(D.x-A.x)-(d.x-a.x);
cc=a.x-A.x;
dd=(B.y-A.y)-(b.y-a.y);
ee=(D.y-A.y)-(d.y-a.y);
ff=a.y-A.y;
y=(ff*1.0-dd/aa*cc)/(ee-dd/aa*bb);
x=(cc-bb*y)/aa;
int xb=A.x+x*(B.x-A.x)+y*(D.x-A.x);
int yb=A.y+x*(B.y-A.y)+y*(D.y-A.y);
cout<<fixed<<setprecision(6)<<xb<<" "<<yb<<endl;
}
return 0;
}