5.17pkusc模拟赛4

A.
B.求只存在简单环的最小环。(5.17)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 5000
#define M 10000
using namespace std;
struct E{int to,nxt;}edge[M*2];
bool vis[N];
int dis[N];
int idx[N],tot,ans,T,n,m;
void addedge(int from,int to){
    edge[tot].to=to;edge[tot].nxt=idx[from];idx[from]=tot++;
}
void dfs(int x,int fa){
    vis[x]=1;
    dis[x]=dis[fa]+1;
    for(int t=idx[x];t;t=edge[t].nxt){
        E e=edge[t];
        if(!vis[e.to]&&e.to!=fa) dfs(e.to,x); 
        if(vis[e.to]&&e.to!=fa) ans=max(ans,dis[x]-dis[e.to]+1);
    }
}
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%d",&T);
    while(T--){
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));
        memset(idx,0,sizeof(idx));tot=1;ans=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            addedge(x,y);addedge(y,x);
        }
        dis[1]=1;dfs(1,0);printf("%d\n",ans);
    }
    return 0;
}

C.n个字符串中出现在一半以上次数的最长子串。(n<=100,maxl<=1000)(5.18)
拼接在一起,利用后缀数组的height二分答案。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 200005
#define pa pair<int,int>
#define mp make_pair 
using namespace std;
char tmp[N],ch[10];
int t1[N],t2[N],c[N],s[N];
int height[N],sa[N],r[N];
int n,t,flag[N],id[N],last[N];
vector<pa>vec,ans;
vector<pa>::iterator it;
void init(){
    memset(t1,0,sizeof(t1));
    memset(t2,0,sizeof(t2));
    memset(c,0,sizeof(c));
    memset(height,0,sizeof(height));
    memset(sa,0,sizeof(sa));
    memset(r,0,sizeof(r));
    memset(flag,0,sizeof(flag));
    memset(id,0,sizeof(id));
    memset(last,0,sizeof(last));
    memset(s,0,sizeof(s));
}
void buildsa(int m){
    int *x=t1,*y=t2;
    for(int i=1;i<=m;i++) c[i]=0;
    for(int i=1;i<=n;i++) c[x[i]=s[i]]++;
    for(int i=1;i<=m;i++) c[i]+=c[i-1];
    for(int i=n;i>=1;i--) sa[c[x[i]]--]=i;
    for(int k=1;k<=n;k<<=1){
        int p=0;
        for(int i=n-k+1;i<=n;i++) y[++p]=i;
        for(int i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;
        for(int i=1;i<=m;i++) c[i]=0;
        for(int i=1;i<=n;i++) c[x[y[i]]]++;
        for(int i=1;i<=m;i++) c[i]+=c[i-1];
        for(int i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i];
        swap(x,y);p=1;x[sa[1]]=1;
        for(int i=2;i<=n;i++)
            x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
        if(p>=n) break;
        m=p;
    }
}
void getheight(){
    for(int i=1;i<=n;i++) r[sa[i]]=i;
    int i,j,k=0;
    for(i=1;i<=n;i++){
        if(k) k--;
        int j=sa[r[i]-1];
        while(s[i+k]==s[j+k]) k++;
        height[r[i]]=k;
    }
}
void cat(char *s1,char *s2){
    int l=strlen(s1+1);
    for(int i=l+1;s2[i-l-1];i++)
        s1[i]=s2[i-l-1];
}
bool judge(int x){
    int node=0,counter=0,l=0;
    memset(flag,0,sizeof(flag));
    memset(last,0,sizeof(last));
    vec.clear();
    for(int i=2;i<=n+1;i++){
        if(height[i]>=x) {
            int ii=sa[i],jj=sa[i-1];
            if(!flag[id[jj]]){
                counter++;
                flag[id[jj]]=1;
                last[id[jj]]=l;
                l=id[jj];
            }
            if(!flag[id[ii]]){
                counter++;
                flag[id[ii]]=1;
                last[id[ii]]=l;
                l=id[ii];
            }
        }
        if(height[i]<x) {
            if(counter*2>t)vec.push_back(mp(sa[i-1],x));
            while(l){
                flag[l]=0;
                int tmp=l;l=last[l];
                last[tmp]=0;
            }
            counter=0;
        }
    }
    vector<pa>::iterator it;
    if(vec.size()){
        ans.clear();
        for(it=vec.begin();it!=vec.end();it++) {
            pa x=*it;
            ans.push_back(x);
        }
        return 1;
    }
    return 0;
}
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    while(scanf("%d",&n)&&n!=0){
        init();
        t=n;int cnt=1,wtf=0;
        scanf("%s",tmp);
        for(int i=0;tmp[i];i++) s[++wtf]=tmp[i];
        for(int i=2;i<=n;i++){
            scanf("%s",tmp);
            if(i<'a') s[++wtf]=i;
            else s[++wtf]=i+30;
            for(int i=0;tmp[i];i++) s[++wtf]=tmp[i];
        }
        n=wtf;
        for(int i=1;i<=n;i++){
            if(s[i]<'a'||s[i]>'z') cnt++;
            else id[i]=cnt;
        }
        buildsa(200);
        getheight();
        int l=0,r=N;
//      for(int i=1;i<=n;i++)
//          if(s[i]<'a'||s[i]>'z')printf("%d\n",s[i]);  
        while(l<r){
            int mid=(l+r)>>1;
            if(judge(mid)) l=mid+1; 
            else r=mid;
        }
        if(l==0) {printf("?\n\n");continue;}
        vector<pa>::iterator it;
        for(it=ans.begin();it!=ans.end();it++){
            pa x=*it;
            for(int i=1;i<=x.second;i++)
                printf("%c",s[x.first+i-1]);
            printf("\n");
        }printf("\n");
    }
    return 0;
}

D.
E.
F.

发布了87 篇原创文章 · 获赞 7 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/yxr0105/article/details/51441529