zoukankan      html  css  js  c++  java
  • ACM题目————一笔画问题

    描述

    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

     可以用并查集做,也可以直接建图做。

    因为正在加班加点的学习数据结构,于是先建图做了一次。

    参考了http://www.cnblogs.com/dongsheng/archive/2012/06/04/2534489.html

    建图:

    //Asimple
    
    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1005;
    int n, T, num, cnt, point, line, x, y;
    int G[maxn][maxn];
    int vis[maxn];//标记数组,标记是否走过
    int p[maxn];//每个节点的度
    
    //图的DFS
    //欧拉图:节点度数全部为偶数
    //半欧拉图:有且只有两个度数为奇数的节点
    //这两种图都可以一笔画出。
    
    void DFS(int i)
    {
        int v;
        vis[i] = 1 ;
        for(v=0; v<point; v++)
            if( v!=i && G[i][v] && !vis[v])
                DFS(v);
    }
    
    int main()
    {
        cin >> T ;
        while( T -- )
        {
            cnt = 0 ;
            bool flag = true ;
            cin >> point >> line ;
            memset(p,0,sizeof(p));
            memset(vis,0,sizeof(vis));
            memset(G,0,sizeof(G));
    
            for(int i=0; i<line; i++)
            {
                cin >> x >> y ;
                G[x-1][y-1] = G[y-1][x-1] = 1 ;//建图
                ++ p[x-1] ;
                ++ p[y-1] ;//统计 各节点的度
            }
            DFS(0);//判断是否连通
            for(int i=0; i<point; i++)
            {
                G[i][i] = 1 ;
                if( vis[i]==0 ) flag = false ;
                if( p[i]&1 ) cnt ++ ;
            }
            if( flag )//是连通图
            {
                if( cnt==0 || cnt==2 ) cout << "Yes" << endl ;
                else cout << "No" << endl ;
            }
            else cout << "No" << endl ;
        }
    
        return 0;
    }
    

     并查集:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    int father[1005], deg[1005];
    
    int find(int k)
    {
        if(k == father[k])
            return k;
        else
            return father[k] = find(father[k]);
    }
    
    int main()
    {
        int T, p, q, a, b;
        
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d", &p, &q);
            for(int i = 1; i <= p; ++i)
            {
                father[i] = i;
                deg[i] = 0;
            }
            
            while(q--)
            {
                scanf("%d%d", &a, &b);
                ++deg[a];
                ++deg[b];
                int fa = find(a);
                int fb = find(b);
                if(fa != fb)
                    father[fa] = fb;
            }
            
            int cnt1, cnt2;
            cnt1 = cnt2 = 0;
            for(int i = 1; i <= p; ++i)
            {
                if(father[i] == i)
                {
                    ++cnt1;
                    if(cnt1 > 1)
                        break;
                }
                if(deg[i] & 1)
                    ++cnt2;
            }
            if(cnt1 > 1)
                printf("No
    ");
            else
            {
                if(cnt2 == 0 || cnt2 == 2)
                    printf("Yes
    ");
                else
                    printf("No
    ");
            }
        }
        return 0;
    }
    
    低调做人,高调做事。
  • 相关阅读:
    Git-Runoob:Git 查看提交历史
    Git-Runoob:Git 分支管理
    Git-Runoob:Git 基本操作
    Git-Runoob:Git 创建仓库
    weblogic11g 安装集群 —— win2003 系统、单台主机
    关于条件宏的易错点
    关于端口号你知道多少!
    POJ 2114 Boatherds【Tree,点分治】
    Android应用开发学习笔记之Intent
    对于接收到的GPS信息详解
  • 原文地址:https://www.cnblogs.com/Asimple/p/5532803.html
Copyright © 2011-2022 走看看