D
题目传送门:D - Medicines on Grid
提示一
直接bfs时间复杂度是O(H^2*W^2),N没用上?
提示二
是不是存在一些关键点呢?
解答
我们用有药水点建图,如果两个药水点可达就连边,最后判断起点和终点所在的药水点是否联通就可以了。
代码
#include<bits/stdc++.h>
using namespace std;
const int D[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int h,w,n,r[301],c[301],e[301],d[201][201],S,T,front,rear,q[40001][2],de[301];
char s[202][202];
vector<int>edges[301];
map<pair<int,int>,int>m;
void bfs(int i){
front=1,rear=0;
d[r[i]][c[i]]=1;
q[++rear][0]=r[i];
q[rear][1]=c[i];
if(s[r[i]][c[i]]=='T'&&!T)
T=i;
while(front<=rear){
int x=q[front][0],y=q[front++][1];
if(d[x][y]>e[i])
continue;
for(int j=0;j<4;j++){
int xx=x+D[j][0],yy=y+D[j][1];
if(xx<1||xx>h||yy<1||yy>w||s[xx][yy]=='#'||d[xx][yy])
continue;
d[xx][yy]=d[x][y]+1;
q[++rear][0]=xx;
q[rear][1]=yy;
if(m.count({xx,yy}))
edges[i].push_back(m[{xx,yy}]);
if(s[xx][yy]=='T'&&!T)
T=i;
}
}
}
void dfs(int i){
for(auto x:edges[i])
if(!de[x])
de[x]=de[i]+1,dfs(x);
}
int main(){
scanf("%d%d",&h,&w);
for(int i=1;i<=h;i++)
scanf("%s",s[i]+1);
scanf("%d",&n);
bool bbbbb=true;
for(int i=1;i<=n;i++){
scanf("%d%d%d",&r[i],&c[i],&e[i]);
m[{r[i],c[i]}]=i;
if(s[r[i]][c[i]]=='S')
bbbbb=false,S=i;
}
if(bbbbb)
return puts("No"),0;
for(int i=1;i<=n;i++){
for(int j=1;j<=h;j++)
for(int k=1;k<=w;k++)
d[j][k]=0;
bfs(i);
}
if(!T)
return puts("No"),0;
de[S]=1;
dfs(S);
if(de[T])
puts("Yes");
else
puts("No");
}
E
题目传送门:E - Minimize Sum of Distances
提示一
从f(u)到f(v(u的相邻点)),函数值会发生什么变化?
解答
我们设u是v的父亲节点,则可以发现f(v)=f(u)-v子树c的和+不是v子树的c的和,所以我们可以先求f(1)然后递推其他f就行了。
代码
#include<bits/stdc++.h>
using namespace std;
int n,c[100001],d[100001];
long long csum[100001],ans;
bool b[100001];
vector<int>edges[100001];
void dfs(int x){
csum[x]=c[x];
for(auto y:edges[x])
if(!d[y]){
d[y]=d[x]+1;
dfs(y);
csum[x]+=csum[y];
}
}
void dfs2(int x){
for(auto y:edges[x])
if(!b[y]){
b[y]=true;
ans=min(ans,ans+csum[1]-csum[y]-csum[y]);
dfs2(y);
}
}
int main(){
scanf("%d",&n);
for(int i=1,a,b;i<n;i++)
scanf("%d%d",&a,&b),edges[a].push_back(b),edges[b].push_back(a);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
d[1]=1;
dfs(1);
for(int i=1;i<=n;i++)
ans+=1LL*c[i]*(d[i]-1);
b[1]=true;
dfs2(1);
printf("%lld\n",ans);
}
F
题目传送门:F - Oddly Similar
解答
卡常好题,不说了,看代码。
代码
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
using namespace std;
char buf[1<<20],*p1,*p2,obuf[1<<20],*p3=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) ((p3-obuf<(1<<20))?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x))
int n,m,a[2001][2001],ans;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
inline void write(int x){
if(!x){
putchar('0');
return;
}
int len=0;
char c[10];
if(x<0)
x=-x,putchar('-');
while(x)
c[len++]=x%10^48,x/=10;
while(len--)
putchar(c[len]);
}
int main(){
n=read();
m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=read();
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
int sum=0;
for(int k=1;k<=m;k++)
if(a[i][k]==a[j][k])
sum++;
ans+=sum%2;
}
write(ans);
fwrite(obuf,p3-obuf,1,stdout);
p3=buf;
}