• 32-一笔画(欧拉图)


       http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=42       

                    一笔画问题

    时间限制: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
    来源
    [张云聪]原创
    上传者
    张云聪
    解题思路:由题意可知为欧拉图(当然我是参考了别人的才知道,呵呵...)
    欧拉图:通过图(无向图或有向图)中所有边一次且仅一次行遍图中所有顶点的通路称为欧拉通路,通过图中所有边一次且仅一次行遍所有顶点的回路称为欧拉回路。具有欧拉回路的图称为欧拉图(Euler Graph),具有欧拉通路而无欧拉回路的图称为半欧拉图。
    首先用数组构建无向图,然后记录同一结点出现的次数,用于判断是否为欧拉图
    欧拉图的性质(无向图):
    1.无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数);
    2.无向连通图G含有欧拉通路,当且仅当G有零个或两个奇数度的结点;
    如果满足欧拉图性质,然后进行dfs,如果深搜次数等于顶点个数即为连通图。
    综上:能一笔画完的图必定满足的条件:1.该图是连通的
                     2.该图的奇度数节点为0或2

    这里用了dfs遍历,由于用二维数组记录图,所以造成很多无谓的访问和判断,效率不是很高,不过还是a了,建议使用邻接表记录图
    判断连通图:可以并查集和dfs
    #include <iostream>
    #include <cstring>
    #include <vector>
    using namespace std;
    vector <int> mp[1005];
    int visit[1005];
    int du[1005];
    
    void dfs(int s){
    	visit[s] = 1;
    	int len = mp[s].size();
    	for(int i = 0; i < len; i++){
    		if(!visit[mp[s][i]]){
    			dfs(mp[s][i]);
    		} 
    	} 
    }
    
    int main(){
    	int n, m;
    	int t;
    	cin >> t;
    	while(t--){
    		memset(visit, 0, sizeof(visit));
    		memset(du, 0, sizeof(du)); 
    		cin >> n >> m;
    		
    		for(int i = 1; i <= n; i++)
    			mp[i].clear();
    		for(int i = 0; i < m; i++){
    			int x, y;
    			cin >> x >> y;
    			mp[x].push_back(y);
    			mp[y].push_back(x);
    			du[x]++;
    			du[y]++;
    		} 
    		dfs(1);
    		for(int i = 1; i <= n; i++){
    			if(!visit[i]){
    				cout << "No" << endl;
    				return 0; 
    			}
    		}
    		int ct = 0;
    		for(int i = 1; i <= n; i++){
    			if(du[i] & 1)
    				ct++;
    		}
    		if(ct == 0 || ct == 2){
    			cout << "Yes" << endl; 
    		}
    		else
    			cout << "No" << endl;
    	}
    	
    	return 0;
    }
    

      

    #include <iostream>
    #include <vector>
    #include <cstring>
    using namespace std;
    int mp[1005];
    int ans[1005];
    
    int find(int x){
    	if(mp[x] == x)
    		return x;
    	else
    		mp[x] = find(mp[x]);
    }
    
    void mix(int x, int y){
    	int xx = find(x);
    	int yy = find(y);
    	if(xx == yy)
    		return ;
    	else
    		mp[x] = yy;
    }
    
    int main(){
    	int t;
    	cin >> t;
    	while(t--){
    		memset(ans, 0, sizeof(ans));
    		int n, m;
    		cin >> n >> m;
    		for(int i = 1; i <= n; i++){
    			mp[i] = i;
    		}
    		for(int i = 0; i < m; i++){
    			int x, y;
    			cin >> x >> y;
    			mix(x, y);
    			ans[x]++;
    			ans[y]++; 
    		}
    		int ct = 0;
    		int du = 0;
    		for(int i = 1; i <= n; i++){
    			if(mp[i] == i)
    				ct++;
    			if(ans[i] & 1)
    				du++;
    		}
    		if(ct == 1 && (du == 0 || du == 2))
    			cout << "Yes" << endl;
    		else
    			cout << "No" << endl;
    	}
    	
    	return 0;
    }
    

      

     
  • 相关阅读:
    [Algorithm] Delete a node from Binary Search Tree
    [Javascript] Check both prop exists and value is valid
    对象的多态性
    spring 定时任务(3)--配置多个定时任务
    能上QQ无法打开网页
    [置顶] Ajax核心--XMLHttpRequest对象
    linux内核--进程地址空间(一)
    [SQL]一个删选数据的例子,使用GROUP、DISTINCT
    [置顶] 腾讯2014软件开发笔试题目
    DBS小结
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/8624822.html
Copyright © 2020-2023  润新知