【字符串】【最小表示法】Vijos P1683 有根树的同构问题
2016-08-20 20:02
337 查看
题目链接:
https://vijos.org/p/1683
题目大意:
给M棵树,每棵N个点,N-1条边,树边有向,问哪些树同构。
题目思路:
【字符串】【最小表示法】
用()表示一个节点,那么三个节点的树 1 2 1 3就可以表示成(()())。
用递归求出每个节点的子树的括号序列,从小到大排序,再在外面加一层(),即为当前结点的括号序列。(这样排完序的括号序列是唯一的)
最终求出每棵树的树根的括号序列,判断是否相等即可。
View Code
https://vijos.org/p/1683
题目大意:
给M棵树,每棵N个点,N-1条边,树边有向,问哪些树同构。
题目思路:
【字符串】【最小表示法】
用()表示一个节点,那么三个节点的树 1 2 1 3就可以表示成(()())。
用递归求出每个节点的子树的括号序列,从小到大排序,再在外面加一层(),即为当前结点的括号序列。(这样排完序的括号序列是唯一的)
最终求出每棵树的树根的括号序列,判断是否相等即可。
// //by coolxxx //#include<bits/stdc++.h> #include<iostream> #include<algorithm> #include<string> #include<iomanip> #include<map> #include<memory.h> #include<time.h> #include<stdio.h> #include<stdlib.h> #include<string.h> //#include<stdbool.h> #include<math.h> #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define abs(a) ((a)>0?(a):(-(a))) #define lowbit(a) (a&(-a)) #define sqr(a) ((a)*(a)) #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define eps (1e-8) #define J 10 #define mod 1000000007 #define MAX 0x7f7f7f7f #define PI 3.14159265358979323 #define N 104 using namespace std; typedef long long LL; int cas,cass; int n,m,lll,ans; double anss; string s1 ; struct xxx { int next,to; }a ; int last ; bool mark ; bool cmp(string aa,string bb) { if(aa.length()!=bb.length())return aa.length()<bb.length(); int i; for(i=0;i<aa.length();i++) if(aa[i]!=bb[i])return aa[i]<bb[i]; } void add(int x,int y) { a[++lll].next=last[x]; a[lll].to=y; last[x]=lll; } string dfs(int u) { string s ; int i,j; for(i=last[u],j=1;i;i=a[i].next,j++) s[j]=dfs(a[i].to); sort(s+1,s+1+j,cmp); string t="("; for(i=1;i<=j;i++)t+=s[i]; t=t+")"; // cout<<u<<" "<<t<<endl; return t; } int main() { #ifndef ONLINE_JUDGE // freopen("1.txt","r",stdin); // freopen("2.txt","w",stdout); #endif int i,j,k; int x,y; // for(scanf("%d",&cas);cas;cas--) // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) // while(~scanf("%s",s+1)) while(~scanf("%d",&m)) { scanf("%d",&n); for(i=1;i<=m;i++) { lll=0; mem(last,0);mem(mark,0); for(j=1;j<n;j++) { scanf("%d%d",&x,&y); add(x,y);mark[y]=1; } for(j=1;j<=n;j++)if(!mark[j])break; s1[i]=dfs(j); } mem(mark,0); for(i=1;i<=m;i++) { if(mark[i])continue; printf("%d",i); mark[i]=1; for(j=i+1;j<=m;j++) if(s1[i]==s1[j]) { printf("=%d",j); mark[j]=1; } puts(""); } } return 0; } /* // // */
View Code
相关文章推荐
- 【字符串】【最小表示法】Vijos P1683 有根树的同构问题
- [转]浅析“最小表示法”思想在字符串循环同构问题中的应用-HDU2609
- 最小表示法 字符串循环同构问题
- Vijos 有根树的同构问题【字符串---最小表示法】
- 【理解字符串循环同构的最小表示法】
- hdu 2609 最小(大)表示法解决同构问题
- 字符串循环同构的最小表示法(转)
- 字符串循环同构——最小表示法の板子
- 理解字符串循环同构的最小表示法
- 理解字符串循环同构的最小表示法
- 最小表示法 (在解决判断“同构”一类问题中有很大作用)
- 【字符串循环同构的最小表示法】
- 字符串循环同构的最小表示法(转)
- 隐藏密码(字符串的同构与最小表示法)
- 字符串同构最小最大表示法模板&&manacher模板
- 字符串同构的最小表示方法
- HDU 2609 How many(字符串同构,最小表示法)
- 【理解字符串循环同构的最小表示法】
- 【理解字符串循环同构的最小表示法】
- 字符串的最小表示法与有根树同构的判定