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\n");
        else
        {
            if(cnt2 == 0 || cnt2 == 2)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}

 

posted @ 2016-05-26 21:49  Asimple  阅读(928)  评论(0编辑  收藏  举报