NOJ [1064] Galaxy

  • 问题描述

  • 输入
  • This problem contains several cases.
    The first line of each case is an integer N (0 < N <= 500), indicates the number of lines.
    Then it follows N line(s). Each line contains 4 integers: The two coordinates of the undirected line. (-500 <= x1, y1, x2, y2 <= 500)
  • 输出
  • For each case, if the galaxy can be linked by the rules above, print YES. Or print NO.

    一笔画问题,那么这个图如果是欧拉图或者是半欧拉图就可以完成
    所谓欧拉图,就是它的所有顶点的度数全是偶数,即奇度顶点的个数是0(无向图)
    所谓半欧拉图,奇度顶点个数为2(无向图)
    好了,还有一个问题就是如何判断这个图是连通的
    这里我用的是并查集,其实可以搜索,但本人比较喜欢并查集,所以就用并查集写了
    #include<stdio.h>
    #include<string.h>
    
    struct F
    {
      int x,y;
      bool operator!=(F a)
      {
        return x!=a.x || y!=a.y;
      }
    }father[1010][1010];
    int node[1010][1010];
    F find(int x,int y) //寻找点(x,y)的祖先 
    {
      if(x==father[x][y].x && y==father[x][y].y)
          return father[x][y];
      father[x][y]=find(father[x][y].x ,father[x][y].y);
          return father[x][y];
    }
    void Union(int x1,int y1,int x2,int y2)
    {
      F temp1=find(x1,y1);
      F temp2=find(x2,y2);
      if(temp2!=temp1)  //其祖先不一样 
      {
        father[temp1.x][temp1.y].x=temp2.x;
        father[temp1.x][temp1.y].y=temp2.y;
      }   
    }
    int main()
    {
      int n;
      int x1,y1,x2,y2;
      while(~scanf("%d",&n))
      {
        int i,j,mx=-1000,my=-1000;
        memset(node,0,sizeof(node));
        for(i=0;i<=1000;i++)
          for(j=0;j<=1000;j++)
          {
            father[i][j].x=i;
            father[i][j].y=j;
          }
        for(i=1;i<=n;i++)
        {
          scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
          x1+=500;
          x2+=500;
          y1+=500;
          y2+=500;
          node[x1][y1]++;
          node[x2][y2]++;
          Union(x1,y1,x2,y2);
          if(mx<x1)  mx=x1;
          if(mx<x2)  mx=x2;
          if(my<y1)  my=y1;
          if(my<y2)  my=y2;
        }
        int ans1=0,ans2=0;
        for(i=0;i<=1000;i++)
          for(j=0;j<=1000;j++)
          {
            if(father[i][j].x==i && father[i][j].y==j && node[i][j])
              ans1++;
            if(node[i][j]%2==1)
              ans2++;
          }
        if(ans1==1 && (ans2==0 || ans2==2))
          printf("YES\n");
        else
          printf("NO\n");
      }
      return 0;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值