弱省互測 2 t2

2022-05-11 21:20:47 字數 1454 閱讀 4046

給兩個樹,大小分別為n和m,現在兩棵樹各選一些點(包括1),使得這棵樹以1號點為根同構(同構就是每個點的孩子數目相同),求最大的同構樹。(n, m<=500)

我們從兩棵樹中各取出乙個點,考慮以這兩個點為根能得到的最大同構數。

容易得到:

設\(d(i, j)\)表示第一棵樹選\(i\)號點,第二棵樹選\(j\)號點所能得到的最大同構數。

那麼\(d(i, j)\)就是等於從\(i\)這個點的子樹選一些點,從\(j\)這個點的子樹選一些點,選出的點數目相同,一一匹配,則答案就是這些點的\(\sum d(x, y)\)。

計算這個我們用最大費用流來計算。

同時我們從深度深的向深度淺的進行計算。

#include using namespace std;

const int n=505, m=n*2;

int ed[2][n][n], ecnt[2][n], n[2], ihead[m], cnt=1;

struct e e[m*m];

void add(int x, int y, int cap, int w) ; ihead[x]=cnt;

e[++cnt]=(e); ihead[y]=cnt;

}int d[m], p[m];

bool spfa(int s, int t, int n)

int y=e[i].to;

if(d[y]>d[x]+e[i].w)

else }}

} }return d[t]!=0x7f7f7f7f;

}void tadd(int x, int y, int w)

int st[2][n][n], scnt[2][n], mxdep;

void dfs(int w, int x, int f, int dep)

dfs(w, y, x, dep+1);

ed[w][x][sz++]=y;

} ecnt[w][x]=sz;

}int f[n][n];

void work(int x, int y)

for(int i=1; i<=c2; ++i)

for(int i=0; i} int &now=f[x][y];

now=1;

while(spfa(s, t, t))

}void dfs(int dep)

int c1=scnt[0][dep], c2=scnt[1][dep];

for(int i=0; i} dfs(dep-1);

}int main()

scanf("%d", &n[1]);

for(int i=1; idfs(0, 1, 0, 0);

dfs(1, 1, 0, 0);

dfs(mxdep);

printf("%d\n", f[1][1]);

return 0;

}

弱省互測 2 t3

給出 n 個01位元組和 m 個01位元組,要求用後者去匹配前者,兩個串能匹配當且僅當除了每個位元組末位不同,其他位都要相同。問匹配後者至少有多少個末位不同。1 le m le n le 2.5 times 10 5 首先我們可以用kmp計算出能匹配的位置,然後單獨考慮末位不同的情況。我們將末尾的位...

弱省互測 0 t2

給定兩個字串 a 和 b,求下面四個問題的答案 1.在 a 的子串中,不是 b 的子串的字串的數量。2.在 a 的子串中,不是 b 的子串行的字串的數量。3.在 a 的子串行中,不是 b 的子串的字串的數量。4.在 a 的子串行中,不是 b 的子串行的字串的數量。其中子串是指本質不同的子串,不同的位...

弱省互測 0 t1

給乙個 n times m 的01網格,1不能走,從起點 1,1 走到 n,m 每次只能向下或向右走一格,問兩條不相交的路徑的方案數。n,m 1000 先考慮一條,再考慮去掉相交的情況。令 d a,b,c,d 表示從 a,b 走到 c,d 一條路徑的方案數,則可以簡單得到答案 ans d 2,1,n...