【字符串】【最小表示法】Vijos P1683 有根树的同构问题
题目链接:
题目大意:
给M棵树,每棵N个点,N-1条边,树边有向,问哪些树同构。
题目思路:
【字符串】【最小表示法】
用()表示一个节点,那么三个节点的树 1 2 1 3就可以表示成(()())。
用递归求出每个节点的子树的括号序列,从小到大排序,再在外面加一层(),即为当前结点的括号序列。(这样排完序的括号序列是唯一的)
最终求出每棵树的树根的括号序列,判断是否相等即可。
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<memory.h> 10 #include<time.h> 11 #include<stdio.h> 12 #include<stdlib.h> 13 #include<string.h> 14 //#include<stdbool.h> 15 #include<math.h> 16 #define min(a,b) ((a)<(b)?(a):(b)) 17 #define max(a,b) ((a)>(b)?(a):(b)) 18 #define abs(a) ((a)>0?(a):(-(a))) 19 #define lowbit(a) (a&(-a)) 20 #define sqr(a) ((a)*(a)) 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 22 #define mem(a,b) memset(a,b,sizeof(a)) 23 #define eps (1e-8) 24 #define J 10 25 #define mod 1000000007 26 #define MAX 0x7f7f7f7f 27 #define PI 3.14159265358979323 28 #define N 104 29 using namespace std; 30 typedef long long LL; 31 int cas,cass; 32 int n,m,lll,ans; 33 double anss; 34 string s1[N]; 35 struct xxx 36 { 37 int next,to; 38 }a[N]; 39 int last[N]; 40 bool mark[N]; 41 bool cmp(string aa,string bb) 42 { 43 if(aa.length()!=bb.length())return aa.length()<bb.length(); 44 int i; 45 for(i=0;i<aa.length();i++) 46 if(aa[i]!=bb[i])return aa[i]<bb[i]; 47 } 48 void add(int x,int y) 49 { 50 a[++lll].next=last[x]; 51 a[lll].to=y; 52 last[x]=lll; 53 } 54 string dfs(int u) 55 { 56 string s[N]; 57 int i,j; 58 for(i=last[u],j=1;i;i=a[i].next,j++) 59 s[j]=dfs(a[i].to); 60 sort(s+1,s+1+j,cmp); 61 string t="("; 62 for(i=1;i<=j;i++)t+=s[i]; 63 t=t+")"; 64 // cout<<u<<" "<<t<<endl; 65 return t; 66 } 67 int main() 68 { 69 #ifndef ONLINE_JUDGE 70 // freopen("1.txt","r",stdin); 71 // freopen("2.txt","w",stdout); 72 #endif 73 int i,j,k; 74 int x,y; 75 // for(scanf("%d",&cas);cas;cas--) 76 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 77 // while(~scanf("%s",s+1)) 78 while(~scanf("%d",&m)) 79 { 80 scanf("%d",&n); 81 for(i=1;i<=m;i++) 82 { 83 lll=0; 84 mem(last,0);mem(mark,0); 85 for(j=1;j<n;j++) 86 { 87 scanf("%d%d",&x,&y); 88 add(x,y);mark[y]=1; 89 } 90 for(j=1;j<=n;j++)if(!mark[j])break; 91 s1[i]=dfs(j); 92 } 93 mem(mark,0); 94 for(i=1;i<=m;i++) 95 { 96 if(mark[i])continue; 97 printf("%d",i); 98 mark[i]=1; 99 for(j=i+1;j<=m;j++) 100 if(s1[i]==s1[j]) 101 { 102 printf("=%d",j); 103 mark[j]=1; 104 } 105 puts(""); 106 } 107 } 108 return 0; 109 } 110 /* 111 // 112 113 // 114 */