題裡給出了沒點的度都小於等於2這個條件,既圖只能是環和鏈組成的圖,其中點包括在鏈裡,這樣只需遍曆下各個連通分量,記錄他們是否是環還是鏈,以及點的個數,之後在排序對比下即可。
#include <cstdio>#include <algorithm>using namespace std;const int inf =0x3fffffff;const int maxn=10005;struct graph{ int chain[maxn],ring[maxn]; int chain_num,ring_num;}g1,g2;struct Edge { int v,next;}edge[2*maxn];int head[maxn],cnt;bool vis[maxn];void addedge (int u,int v){ edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].next=head[v]; head[v]=cnt++;}bool is_same(){ sort (g1.chain,g1.chain+g1.chain_num); sort (g2.chain,g2.chain+g2.chain_num); for (int i=0 ; i<g1.chain_num ; ++i) if(g1.chain[i]!=g2.chain[i])return false; sort (g1.ring,g1.ring+g1.ring_num); sort (g2.ring,g2.ring+g2.ring_num); for (int i=0 ; i<g1.ring_num ; ++i) if(g1.ring[i]!=g2.ring[i])return false; return true;}void init (graph &g){ memset (g.chain , 125 , sizeof(g.chain)); memset (g.ring , 125 , sizeof(g.ring)); g.chain_num=g.ring_num=0; memset (head , -1 , sizeof(head)); memset (vis , 0 , sizeof(vis)); cnt=0;}bool is_ring;void dfs (int u,int &num,int fath){ vis[u]=true; num++; for (int p=head[u]; ~p ; p=edge[p].next) { int v=edge[p].v; if(v==fath)continue; if(vis[v])is_ring=true; if (!vis[v]) { dfs(v,num,u); } }}int m,n,u,v,i,j;void solve(graph &g){ init(g); scanf("%d%d",&n,&m); for (i=0 ; i<m ; ++i) { scanf("%d%d",&u,&v); u--,v--; addedge(u,v); } int count; for (i=0 ; i<n ; ++i) { if (!vis[i]) { count=1; is_ring=false; dfs(i,count,inf); if(is_ring)g.ring[g.ring_num++]=count; else g.chain[g.chain_num++]=count; } }}int main (){ int cas; //freopen ("G.txt","r",stdin); //freopen ("out.txt","w",stdout); scanf("%d",&cas); for (int I=1 ; I<=cas ; ++I) { solve(g1); solve(g2); printf("Case #%d: %s\n",I,is_same()?"YES":"NO"); } return 0;}