POI 2001 跳舞蝇

来源:互联网 发布:学习软件测试难吗 编辑:程序博客网 时间:2024/04/30 15:40

02年的论文题,论文里的方法看不懂QAQ。

然后07年的论文里有一个有向图的同构判定,于是拿来水一水。

结果……


呵呵呵呵呵呵呵呵呵

让我静一静TAT

我觉得肯定是评测机太慢了,我的复杂度是d*n*k的

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef unsigned long long ll;const int a=566;const int b=346;const int c=489;ll f1[2005][55],f2[2005][55],s[2005];int p1[2005],p2[2005],n;void solve(ll f[2005][55],int p[2005],int k){for(int i=1;i<=n;i++)s[i]=0;for(int i=1;i<=n;i++){f[i][k]=f[i][k-1]*a+f[p[i]][k-1]*b;s[p[i]]+=f[i][k-1];}for(int i=1;i<=n;i++)f[i][k]+=s[i]*c;}int t1[2005],t2[2005];bool check(){for(int i=1;i<=n;i++)f1[i][0]=f2[i][0]=1;for(int i=1;i<=33;i++){solve(f1,p1,i);solve(f2,p2,i);for(int j=1;j<=n;j++){t1[j]=f1[j][i];t2[j]=f2[j][i];}sort(t1+1,t1+1+n);sort(t2+1,t2+1+n);for(int j=1;j<=n;j++)if(t1[j]!=t2[j])return 0;}return 1;}int main(){//freopen("a.in","r",stdin);int T;scanf("%d",&T);while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&p1[i]); for(int i=1;i<=n;i++)scanf("%d",&p2[i]);  puts(check()?"T":"N");}return 0;}

昨天睡觉的时候突然想起来这个是基环内向树哎。

既然是这样的话我们当然不能用普通的图的hash了。

首先考虑树的部分,当然是有根树的hash了,这个很好搞。

然后设有根树的根在环上。

当然我们知道每条链的尽头都是环(自环也是环)

于是我们想一下环可以怎么hash。

环?循环?字符串的循环同构?(不要问我怎么想到的)

于是我们可以把环看成一个串,串上每个字符就是这个点所连的树的hash值。

然后对每个环求hash值。

最后排序一下比较所有环的hash值(一一对应)


啦啦啦啦啦啦啦啦啦了~

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>using namespace std;typedef unsigned long long ll;const int a=233;const int b=213;const int c=417;const int N=2000+5;vector<ll>v[N];ll w[N],xa[N];int p[N],du[N],n;void toposort(){queue<int>q;for(int i=1;i<=n;i++)if(!du[i])q.push(i);while(!q.empty()){int u=q.front();q.pop();ll ans=0;sort(v[u].begin(),v[u].end());for(int i=0;i<v[u].size();i++)ans=ans*a+v[u][i];w[u]=ans+xa[v[u].size()+1];du[p[u]]--;v[p[u]].push_back(w[u]);if(!du[p[u]])q.push(p[u]);}for(int i=1;i<=n;i++)if(du[i]){ll ans=0;sort(v[i].begin(),v[i].end());for(int j=0;j<v[i].size();j++)ans=ans*a+v[i][j];w[i]=ans+xa[v[i].size()+1];w[i]+=c;}}void findcircle(vector<ll>& g){g.clear();for(int i=1;i<=n;i++)if(du[i]){vector<ll>f;int j=i;do{f.push_back(w[j]);j=p[j];}while(j!=i);sort(f.begin(),f.end());ll ans=0;for(j=0;j<f.size();j++)ans=ans*b+f[j];g.push_back(ans);}sort(g.begin(),g.end());}vector<ll>f,g;void init(){for(int i=1;i<=n;i++){v[i].clear();du[i]=0;}}int main(){//freopen("a.in","r",stdin);int T;scanf("%d",&T);xa[0]=1;for(int i=1;i<=2000;i++)xa[i]=xa[i-1]*a;while(T--){scanf("%d",&n);init();for(int i=1;i<=n;i++){scanf("%d",&p[i]);du[p[i]]++;}toposort();findcircle(f);init();for(int i=1;i<=n;i++){scanf("%d",&p[i]);du[p[i]]++;}toposort();findcircle(g);puts(f==g?"T":"N");}return 0;}


0 0
原创粉丝点击