4 1 1 1 2 2 3 2 4 3 1 2 2 3 3 1
NO YES Hint For the second testcase, One of the path is 1->2->3 If you doesn't know what is Hamiltonian path, click here (https://en.wikipedia.org/wiki/Hamiltonian_path).
删除自环,如果自环个数>1无解,=1,判定是否联通即可。
=0,枚举每条边,删除,然后判定联通。
1号点用于判定联通,因为1可能不是路径的起点,所以要从两个方向搜索。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<vector> using namespace std; #define maxn 3001 int size[maxn]; int nv[maxn],nextt[maxn],id[maxn]; int head[maxn]; int check[maxn]; void dfs(int u,int f,int xid){ if(check[u]) return ; //cout<<u<<"->"; check[u] = 1; size[u] = 1; int t= 0; for(int i = head[u];i != -1; i = nextt[i]){ if(id[i] == xid) continue; int v = nv[i]; if(check[v]) continue; dfs(v,u,xid); size[u]+=size[v]; if(u == 1 && t == 0){ t++; continue; } return ; } } int in[maxn]; int main(){ int n,u,v; while(scanf("%d",&n)!=EOF){ memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); int cnt = 0,cycle=0; for(int i = 0;i < n; i++){ scanf("%d%d",&u,&v); if(u == v){ cycle++; continue; } nv[cnt] = u; nextt[cnt] = head[v]; id[cnt] = i; head[v] = cnt++; nv[cnt] = v; nextt[cnt] = head[u]; id[cnt] = i; head[u] = cnt++; if(u != v) in[u]++,in[v]++; } int flag = 0; if(cycle == 1){ memset(check,0,sizeof(check)); dfs(1,0,-1); if(size[1] == n) flag = 1; } else if(cycle == 0) for(int i = 0;i < n && flag==0; i++){ memset(check,0,sizeof(check)); dfs(1,0,i); //cout<<endl; if(size[1] == n) flag = 1; } if(flag)cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }