hdu 3926 Hand in Hand【同構圖】
阿新 • • 發佈:2018-11-24
文章目錄
題目連結:
http://acm.hdu.edu.cn/showproblem.php?pid=3926
題意:給兩個圖,判斷他是否是同構圖
以前只見過一次同構的題,連同構的意思都忘了T_T
這個2018暑假牛客多校(一)D是我第一次也是唯一一次聽到同構的時候
要判斷兩個圖是不是同構貌似是很難的,牛客多校那個好像才8個頂點哇,而我們這道題點雖然比較多,但是有個很關鍵的限制條件
就是一個人只有兩隻手,也就是說構成的圖的樣子不可能是那種亂七八糟的圖,要麼是個環,要麼是條鏈,把這這兩種東西都找出來然後對比看是不是一樣的就行了,這題寫起來感覺有點煩,跟個模擬題一樣,我忘了初始化也貢獻了一發WA
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const int maxn=1e4+5;
const int MOD=1e9+7;
int in1[maxn],in2[maxn];
int fa1[maxn],fa2[maxn];
int Find1(int x)
{
if(x==fa1[x])return x;
else return fa1[x]=Find1(fa1[x]);
}
int Find2(int x)
{
if(x== fa2[x])return x;
else return fa2[x]=Find2(fa2[x]);
}
map<int,int>Mp1,Mp2;
vector<int>vec1[maxn],vec2[maxn];//儲存fa相同的點,用來判斷是環還是鏈
int judge(vector<int>v,int cmd)
{
if(cmd==1)
{
for(int i=0;i<v.size();i++)if(in1[v[i]]==1)return 1;//如果是鏈的話,那麼有一個點的度就是1
return 2;//不然就都是2
}
else
{
for(int i=0;i<v.size();i++)if(in2[v[i]]==1)return 1;
return 2;
}
return 0;//不然就是單點
}
int main()
{
int T;
cin>>T;
for(int Case=1;Case<=T;Case++)
{
for(int i=1;i<=10000;i++)vec1[i].clear(),vec2[i].clear();
Mp1.clear();
Mp2.clear();
memset(in1,0,sizeof in1);
memset(in2,0,sizeof in2);
cin>>N1>>M1;
for(int i=1;i<=N1;i++)fa1[i]=i;
for(int i=1;i<=M1;i++)
{
int u,v;
cin>>u>>v;
in1[u]++,in1[v]++;
u=Find1(u),v=Find1(v);
fa1[u]=v;
}
cin>>N2>>M2;
for(int i=1;i<=N2;i++)fa2[i]=i;
for(int i=1;i<=M2;i++)
{
int u,v;
cin>>u>>v;
in2[u]++,in2[v]++;
u=Find2(u),v=Find2(v);
fa2[u]=v;
}
for(int i=1;i<=N1;i++)fa1[i]=Find1(fa1[i]),fa2[i]=Find2(fa2[i]);
vector<int>root1,root2;
for(int i=1;i<=N1;i++)
{
if(fa1[i]==i)root1.push_back(i);
vec1[fa1[i]].push_back(i);
}
for(int i=1;i<=N2;i++)
{
if(fa2[i]==i)root2.push_back(i);
vec2[fa2[i]].push_back(i);
}
vector<int>lian1,quan1,lian2,quan2;
for(int i=0;i<root1.size();i++)
{
int t=judge(vec1[root1[i]],1);
if(t==1)lian1.push_back(vec1[root1[i]].size());
else if(t==2)quan1.push_back(vec1[root1[i]].size());
}
for(int i=0;i<root2.size();i++)
{
int t=judge(vec2[root2[i]],2);
if(t==1)lian2.push_back(vec2[root2[i]].size());
else if(t==2)quan2.push_back(vec2[root2[i]].size());
}
cout<<"Case #"<<Case<<": ";
if(lian1.size()!=lian2.size()||quan1.size()!=quan2.size())//這裡最好特判一哈,不然後面長度不同要RE
{
puts("NO");
continue;
}
sort(lian1.begin(),lian1.end());
sort(lian2.begin(),lian2.end());
sort(quan1.begin(),quan1.end());
sort(quan2.begin(),quan2.end());
int flag=1;
for(int i=0;i<lian1.size();i++)
{
if(lian1[i]!=lian2[i])flag=0;
}
for(int i=0;i<quan1.size();i++)
{
if(quan1[i]!=quan2[i])flag=0;
}
if(flag)puts("YES");
else puts("NO");
}
}