Time:2018.4.27 17:00-22:00
Link
A
题意
分析
几何最短路,留坑
B solved by ym
题意
ym:按题意模拟即可
C solved by ym
题意
ym:赛时czh的代码FST了,按题意模拟不断删点,实际上和拓扑排序删点相似
#include
using namespace std;
int head[300003*2],nxt[300003*2],to[300003*2],tot;
int C,P,X,L;
int d[200005],del[200005];
bool vis[200005];
void add(int u,int v)
{
++tot;
to[tot]=v;
nxt[tot]=head[u];
head[u]=tot;
}
void topsort()
{
queueq;
q.push(L);
vis[L]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
del[v]++;
if(!vis[v]&&del[v]>=((d[v]+1)/2))
{
vis[v]=1;
q.push(v);
}
}
}
}
int main()
{
scanf("%d%d%d%d",&C,&P,&X,&L);
int u,v;
for(int i=1;i<=P;i++)
{
scanf("%d%d",&u,&v);
d[u]++;
d[v]++;
add(u,v);
add(v,u);
}
topsort();
if(vis[X])
{
cout<<"leave"<
D
题意
现有n艘船需要通过桥,但桥很累不想一直连通,所以在“闲”的时候可以不连通,但每艘船不可以等待超过30min,升/降桥会花费60s,每艘船通过花费20s,船一艘一艘的通过,给出每艘船到达桥的时间T_i,问船工作的最小时间(升降+连通) ( n<=4000,T_i<=1e5,i
分析
ym:令f_i为前艘船通过的最小时间,枚举和i一起通过的船j(j<=i),转移即可
时间复杂度O(n^2)
#include
using namespace std;
int dp[4005],n,a[4005];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
dp[i]=1000000+7;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
dp[1]=140;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
dp[i]=min(dp[i], dp[j-1]+120+20+a[i]-min(a[j]+1800,a[i]-(i-j)*20));
}
}
printf("%d\n",dp[n]);
return 0;
}
E
题意
给一个n个点m条边的无向图,给出起点到终点的路径最大值,问满足路径和小于max的所有路径中每条路径的最大值最小(n<=1e4,m<=1e5,w<=1e9)
分析
ym:比赛时候天马行空的考虑完全图路径很多的情况==,实际上至于只需要关注每一个点和边的访问次数,便能正确得出时间复杂度,例如在有权的无向图中的单源最短路,由于每个点只会被取出一次所以时间复杂度为(VlogV),回到此题,二分答案(最短路具有单调性)最短路检查即可(边权w如果大于mid,相当于看做不选择这条边即可,在剩下的点中求最短路径)
时间复杂度O(nlog2n)
#include
using namespace std;
typedef long long LL;
const int maxn=210000;
priority_queue,vector >,greater > > q;
const LL INF=1e18;
LL dis[110000];
int vis[110000];
int n,m,x;
int head[maxn],nxt[maxn],to[maxn],tot;
LL w[210000];
void add(int u,int v,int c)
{
++tot;
to[tot]=v;
w[tot]=c;
nxt[tot]=head[u];
head[u]=tot;
}
LL dij(int limt)
{
for(int i=1;i<=n;i++)
dis[i]=INF,vis[i]=0;
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty())
{
int now=q.top().second;
q.pop();
if(vis[now])
continue;
vis[now]=1;
for(int i=head[now];i!=0;i=nxt[i])
{
if (w[i]<=limt&&dis[to[i]]>dis[now]+w[i])
{ dis[to[i]]=dis[now]+w[i];
q.push(make_pair(dis[to[i]],to[i]));
}
}
}
return dis[n];
}
LL dist;
int ans;
int check(int x)
{
return dij(x)<=dist;
}
int main()
{
scanf("%d%d%d", &n, &m,&x);
int u,v;
int c;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&c);
add(u,v,c);
add(v,u,c);
}
dist=dij(1000000000);
dist=dist*(100LL+x)/100;
int l=1,r=1000000000;
while (l<=r)
{
int mid=(l+r)/2;
if (check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}
F
题意
分析
几何模拟,留坑
G
题意
分析
ym:可做几何,待补
H
题意
分析
ym:爆搜剪纸,待补
I solved by czh&ym
题意
ym:按题意模拟即可
J solved by ym&czh
题意
分别给出n个学生和n个导师的二维坐标,定义两点的dis:|x1-x2|+|y1-y2|,现要一 一配对,要使最大的dis最小,问每个最大所有情况最小的dis
分析
ym:算法理解不深刻,只会套板子
二分图是根据边集,不断找增广路,故可以二分答案,二分图check,即在找增广路的时候加上约束条件
#include
#define ll long long
using namespace std;
const int maxn = 100+7;
int n,f[maxn],v[maxn];
ll sx[maxn],sy[maxn],tx[maxn],ty[maxn];
ll _abs(ll x){
if(x>0) return x;
else return -x;
}
ll dis(int i,int j){
return _abs(sx[i]-tx[j])+_abs(sy[i]-ty[j]);
}
bool found(int x,ll mid)
{
for(int i=1;i<=n;i++)
{
if(dis(x,i)<=mid&&!v[i])
{
v[i]=1;
if(f[i]==0||found(f[i],mid))
{
f[i]=x;
return true;
}
}
}
return false;
}
bool check(ll mid)
{
for(int i=1;i<=n;i++)
f[i]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) v[j]=0;
if(!found(i,mid))
return false;
}
return true;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&sx[i],&sy[i]);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&tx[i],&ty[i]);
bool flag=true;
ll l=0,r=1000000000;
while(l
K
题意
给出长度为L的圆形跑道,每S米至少放一个人,问方案数
分析
ym:dp待补
L solved by czh&ym
题意
ym:排序后检查相邻3项能否形成三角形即可
Summary
Ym:这次表现看上去不错,,其实很惨,数据有锅,Link以Update,kattis数据正确(甚至很强,E卡我两个小时),以后比赛多读几道题,利于补题呀!!!
Czh: