1. 程式人生 > >hdu 3926 Hand in Hand【同構圖】

hdu 3926 Hand in Hand【同構圖】

文章目錄

題目連結:

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"); } }