版权声明:小蒟蒻的博客转载也请注明出处哦 https://blog.csdn.net/qq_42835823/article/details/83625592
【NOIP2015 提高组 信息传递】
tarjan
这道题用tarjan就可以了,判一下有向图强联通就好了,
如果强连通的点大于一就和ans取一个min。
【图可能不联通,所以要加一个循环】
#include<bits/stdc++.h>
using namespace std;
int n,a[200005],ans;
int dfn[200005],low[200005],tot=0,vis[200005];
stack<int>s;
void tarjan(int x){
dfn[x]=low[x]=++tot;
vis[x]=1;
s.push(x);
int y=a[x];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[y],low[x]);
}
else if(vis[y])low[x]=min(dfn[y],low[x]);
if(low[x]==dfn[x]){
int cn=0;
while(1){
int u=s.top();s.pop();
cn++;vis[x]=0;
if(u==x){
if(cn>1)ans=min(ans,cn);
break;
}
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ans=0x7fffffff;
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
printf("%d",ans);
return 0;
}
【NOIP2017提高组DAY1T2 时间复杂度】
大模拟!!!
直接模拟就好了,不过细节太多了!!!!!
我挂了6次才AC~~
- 逻辑运算符打错了
- vis数组复原时char忘记减‘a’了
- 不小心把9打成了1
- flag2(f2)【if(x>y)】所在的循环结束时忘记清零
- 没有把x,y当成数,当成数字(一位数)了
- 用变量读入而不是数组,导致存储出问题
- 终于A了~~~~~~~~~~~~~~~
#include<bits/stdc++.h>
using namespace std;
int t,n,top=0,vis[30],flag=0,res=0,ans=0,mx=0,f2=0;
char s[10],c,stk[120],a[20];
int main(){
scanf("%d",&t);
while(t--){
top=flag=res=ans=mx=f2=0;
memset(vis,0,sizeof(vis));
scanf("%d",&n);
scanf("%s",s);
for(int i=1;i<=n;i++){
scanf("%c",&c);
while(c!='F'&&c!='E')scanf("%c",&c);
if(c=='F'){
scanf("%c",&c);
while('a'>c||c>'z')scanf("%c",&c);
if(vis[(int)(c-'a')])flag=2;
vis[(int)(c-'a')]=1;
stk[++top]=c;
int x=c-'a';
while(!isdigit(c)&&c!='n')scanf("%c",&c);
int r=0,p=0;
if(c=='n')r=-1;
else{
while(c>='0'&&c<='9'){
r=(r<<3)+(r<<1)+(c^48);
scanf("%c",&c);
}
}
scanf("%s",a);
if(f2){
res++;
continue;
}
if(a[0]!='n'){
for(int i=0;i<strlen(a);i++){
p=(p<<3)+(p<<1)+(a[i]^48);
}
}
if(a[0]!='n'&&r>p){
res++;
if(!f2)f2=x;
continue;
}
if(a[0]=='n'&&r==-1)res++;
if(a[0]!='n'&&r==-1){
res++;
if(!f2)f2=x;
}
if(a[0]!='n'&&r!=-1)res++;
}
else{
if(top==0)flag=2;
else{
mx=max(top,mx);
vis[stk[top]-'a']=0;
top--;
if(top==0){
ans=max(mx-res,ans);
f2=res=mx=0;
}
}
}
}
if(flag==2||top!=0){
printf("ERR\n");continue;
}
if(ans==0){
if(s[3]!='^'){
printf("Yes\n");
}
else printf("No\n");
continue;
}
int w=0;
for(int i=4;i<=strlen(s);i++){
if(!isdigit(s[i]))break;
w=(w<<3)+(w<<1)+(s[i]^48);
}
if(w==ans)printf("Yes\n");
else printf("No\n");
}
return 0;
}
【NOIP2017提高组DAY2T1】
并查集
题解:* _ *
这么简单的题,我还WA了两次,哎~~~~~~~~~~~~~
- vector忘记清零
- 乘法时忘记用(long long)了
#include<bits/stdc++.h>
using namespace std;
int t,n,h,r,a[1010],b[1010],c[1010],fa[1010];
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
vector<int>t1;//到达顶部
vector<int>t2;//到达底部
int main(){
scanf("%d",&t);
while(t--){
t1.clear();
t2.clear();
scanf("%d%d%d",&n,&h,&r);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i],&b[i],&c[i]);
for(int j=1;j<i;j++){
if((long long)(a[i]-a[j])*(a[i]-a[j])+(long long)(b[i]-b[j])*(b[i]-b[j])+(long long)(c[i]-c[j])*(c[i]-c[j])>(long long)4*r*r)continue;
int f1=find(i),f2=find(j);
if(f1!=f2)fa[f1]=f2;
}
if(c[i]-r<=0)t1.push_back(i);
if(c[i]+r>=h)t2.push_back(i);
}
int r=0;
for(int i=0;i<t1.size();i++)
if(!r)for(int j=0;j<t2.size();j++)
if(find(t1[i])==find(t2[j])){
printf("Yes\n");
r=1;
break;
}
if(!r)printf("No\n");
}
return 0;
}