一笔画问题
时间限制:3000 ms | 内存限制:65535 KB
难度:4
- 描述
-
zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。
规定,所有的边都只能画一次,不能重复画。
- 输入
- 第一行只有一个正整数N(N<=10)表示测试数据的组数。
每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<=2000),分别表示这个画中有多少个顶点和多少条连线。(点的编号从1到P)
随后的Q行,每行有两个正整数A,B(0<A,B<P),表示编号为A和B的两点之间有连线。 - 输出
- 如果存在符合条件的连线,则输出"Yes",
如果不存在符合条件的连线,输出"No"。 - 样例输入
-
2 4 3 1 2 1 3 1 4 4 5 1 2 2 3 1 3 1 4 3 4
- 样例输出
-
No Yes
讲解,这一道题仔细理解意思会发现,和“吝啬的国度”那道题很像;就是搜索的方式不同
代码如下:1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int N=10000; 7 int visit[N]; 8 int cnt; 9 vector< int >cc[N]; 10 void dfs(int x) 11 { 12 visit[x]=1; 13 int next=-1; 14 for(int i=0;i<cc[x].size();i++) 15 { 16 int tmp=cc[x][i]; 17 if(!visit[tmp]) 18 { 19 next=tmp; 20 break; 21 } 22 } 23 if(-1!=next) 24 dfs(next); 25 } 26 int main() 27 { 28 int t,m,n,a,b,i; 29 cin>>t; 30 while(t--) 31 {int max=0; 32 cin>>m>>n; 33 for(i=1;i<=n;i++) 34 { 35 cin>>a>>b; 36 cc[a].push_back(b); 37 cc[b].push_back(a); 38 } 39 int start=1; 40 for(i=2;i<=m;++i) 41 { 42 if(cc[i].size()<cc[start].size()) 43 start=i; 44 } 45 dfs(start); 46 bool flag=true; 47 for(i=1;i<=m;i++) 48 if(!visit[i]) 49 { 50 flag=false; 51 break; 52 } 53 if(!flag) 54 cout<<"No"; 55 else 56 { 57 int j=0; 58 for(i=1;i<=m;i++) 59 if(cc[i].size()&1) 60 j+=1; 61 if(2==j ||0==j) 62 cout<<"Yes"; 63 else cout<<"No"; 64 } 65 for(i = 0; i <=m; ++i) 66 { 67 visit[i]=0;cc[i].clear(); 68 } 69 cout<<endl; 70 } 71 return 0; 72 }
1 #include<stdio.h> 2 #include<string.h> 3 using namespace std; 4 int Edge[2001][2001],visited[1001],degree[4005]; 5 void dfs(int cur,int v) 6 { 7 visited[cur]=1; 8 int i; 9 for(i=1;i<=v;i++) 10 if(Edge[cur][i]) //从邻接顶点往下寻找并计算出结点的度 11 { 12 degree[cur]++; 13 if(!visited[i]) //标记邻接顶点 14 dfs(i,v); 15 } 16 } 17 int main() 18 { 19 int test; 20 scanf("%d",&test); 21 while(test--) 22 { 23 int v,e; 24 memset(Edge,0,sizeof(Edge)); 25 memset(visited,0,sizeof(visited)); 26 memset(degree,0,sizeof(degree)); 27 scanf("%d%d",&v,&e); 28 int j,x,y,ok=1; 29 for(j=1;j<=e;++j) 30 { 31 scanf("%d%d",&x,&y); 32 Edge[x][y]=Edge[y][x]=1; 33 } 34 dfs(1,v); 35 for(j=1;j<=v;++j) //循环判断图是否连通 36 { 37 if(visited[j]==0) 38 { 39 ok=0; //如果有点没有被连到 40 break; 41 } 42 } 43 if(!ok) printf("No "); 44 else 45 { 46 j=0; 47 for(int k=1;k<=v;++k) 48 if(degree[k]%2!=0) 49 j+=1; 50 if(j==2||j==0) //j=2时,则有两个点必为起点和终点,j=0,则任意点为起始点 51 printf("Yes "); 52 else 53 printf("No "); 54 } 55 } 56 }