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.