思路:(1).用搜索或者并查集判断是否连通 (2).用欧拉图判断是否可以一笔走完
并查集
#include<iostream> #include<cstdio> #include<string.h> using namespace std; int father[2222]; int rank[2222]; int degree[2222]; int find(int x) { return x==father[x]?x:find(father[x]); } void Union(int x,int y) { x=find(x); y=find(y); if(x==y) return ; if(rank[x]>rank[y]) { father[y]=x; rank[x]++; } else { if(rank[x]==rank[y]) rank[y]++; father[x]=y; } } int main() { int i,t; cin>>t; while(t--) { memset(degree,0,sizeof(degree)); int n,m; cin>>n>>m; for(i=0;i<=n;++i) father[i]=i,rank[i]=0; int sum=0,cnt=0; while(m--) { int x,y; cin>>x>>y; degree[x]++; degree[y]++; // x=find(x); 可以去掉这三个,也可以保留 // y=find(y); // if(x!=y) Union(x,y); } for(i=1;i<=n;++i) { if(find(i)==i) cnt++; if(degree[i]%2==1) sum++; } if((sum==0 || sum==2) && cnt==1) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
深搜
#include<iostream> #include<cstdio> #include<string.h> using namespace std; int map[2222][2222],v[2222],degree[2222],P,Q; void dfs(int cur) { int i; v[cur]=1; for(i=1;i<=P;++i) if(map[cur][i]) { degree[cur]++; if(!v[i]) dfs(i); } } int main() { int i,j,N; cin>>N; while(N--) { int A,B,ok=1; memset(map,0,sizeof(map)); memset(v,0,sizeof(v)); memset(degree,0,sizeof(degree)); cin>>P>>Q; for(i=0;i<Q;++i) { cin>>A>>B; map[A][B]=1; map[B][A]=1; } dfs(1); for(i=1;i<=P;++i) if(!v[i]) { ok=0; break; } j=0; for(i=1;i<=P;++i) if(degree[i]%2) j+=1; if((j==0 || j==2) && ok) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }