【字符串】【最小表示法】Vijos P1683 有根树的同构问题

题目链接:

  https://vijos.org/p/1683

题目大意:

  给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 */
View Code

 

posted @ 2016-08-20 20:02  Cool639zhu  阅读(418)  评论(0编辑  收藏  举报