zoukankan      html  css  js  c++  java
  • poj 1300 欧拉回路、通路 解题报告

    最近学了一些dp的皮毛之后,现在开始图论知识的学习,说实话,初步不知道怎么弄这个,然后无意间在网上下了一本关于图论的算法设计程序的教程,然后感觉还不错,结果后面才发现原来多年前,我的师兄就给了我这样一本好的资料。

    感觉有点小悲催啊。。~   有点对不起师兄的感觉,然后今天终于写了一个小知识点,欧拉回路的一题,其实这个也包含了通路的知识。

    还是说一下题意吧。。 

    现在你是一个豪宅的管家,因为你有个粗心的主人,所以需要你来帮忙管理,输入会告诉你现在一共有多少个房间,然后会告诉你从哪个房间出发,你的任务就是从出发的房间通过各个房间之间的通道,来把所有的门都关上,然后最后回到0的房间。

    一开始写的时候,我想因为我自己不是很熟悉图论的知识点,所以我就想用模拟的方法来做一做,结果让我碰对了,说实话  我不知道这样的深搜都可以过。。

    View Code
      1   #include<iostream>
      2   #include<stdio.h>
      3   using namespace std;
      4   int graph[22][22]; 
      5   int n,Count,edgetotal,flag;
      6   void dfs(int i)
      7   {
      8        if(flag)return ;
      9        if(i==0&&Count==edgetotal){flag=1;return ;}//当你回到0房间的时候已经关闭了所有的门,那么就可以完成
     10        for(int j=0;j<n;j++)
     11        {
     12           if(graph[i][j]>0)
     13           {
     14               graph[i][j]--;
     15               graph[j][i]--;
     16               Count++;
     17               dfs(j);
     18               if(flag)return ;
     19               graph[i][j]++;
     20               graph[j][i]++;
     21               Count--;
     22           }     
     23        }
     24   }
     25   int main()
     26   {
     27      char temp[100];
     28      int start,end;
     29      while(gets(temp))
     30      {
     31         if(!strcmp(temp,"ENDOFINPUT"))break;
     32         flag=Count=edgetotal=0;
     33         int len=strlen(temp),sub=6;
     34         n=start=0;
     35         while(temp[sub]!=' '){start=start*10+(temp[sub]-48);sub++;}sub++;
     36         while(sub<len){n=n*10+(temp[sub]-48);sub++;}
     37         memset(graph,0,sizeof(graph));
     38         for(int i=0;i<n;i++)
     39         {
     40              gets(temp);
     41              len=strlen(temp);
     42              for(int j=0;j<len;j++)
     43              {
     44                 end=0;
     45                 while(temp[j]!=' '&&j<len){end=end*10+(temp[j]-48);j++;}
     46                 graph[i][end]++;
     47                 graph[end][i]++;
     48                 edgetotal++;
     49              }
     50         }
     51         gets(temp);
     52         dfs(start);
     53         if(flag)printf("YES %d\n",edgetotal);
     54         else
     55         printf("NO\n");
     56      }
     57      return 0;    
     58   }
     59   其实实际上,最好的解题方法还是来自图论当中的知识,相信有一点图论知识的人都知道,现在给你n个节点,那么这些节点当中如果每个节点的度都是偶数的话,那么一定可以从一个点出发然后回到这个点,并且访问整个路径当中的边。
     60   如果是要测试出通路的话,那么就是检查是否存在两个度为基数的节点,两个节点分别为起点和终点。
     61   #include<iostream>
     62   #include<stdio.h>
     63   using namespace std;
     64   int main()
     65   {
     66       char temp[100];
     67       int door_start,room,door[25],door_total;
     68       int door_num;//度数为基数的节点个数 
     69       while(scanf("%s",temp))
     70       {
     71              if(!strcmp(temp,"ENDOFINPUT"))break;
     72              scanf("%d%d",&door_start,&room);
     73              getchar();
     74              memset(door,0,sizeof(door));
     75              door_total=0;
     76              for(int i=0;i<room;i++)
     77              {
     78                 gets(temp);
     79                 int len=strlen(temp);
     80                 for(int j=0;j<len;j++)
     81                 {
     82                    int end=0;
     83                    while(temp[j]!=' '&&j<len){end=end*10+temp[j]-48;j++;}
     84                    door[i]++;
     85                    door[end]++;
     86                    door_total++;
     87                 }
     88              }
     89              gets(temp);
     90              door_num=0;
     91              for(int i=0;i<room;i++)
     92              {
     93                  if(door[i]%2)door_num++;
     94              }      
     95              if(door_num==0&&door_start==0)printf("YES %d\n",door_total);
     96   //如果不存在基数度的节点,那么当起点是0的时候,一定可以完成回路,访问所有的边。           
     97   else
     98              if(door_num==2&&door[0]%2==1&&door[door_start]%2==1&&door_start!=0)printf("YES %d\n",door_total);//如果基数点为2的话,那么当两个基数点为起点和终点的时候,此时只要终点与起点不重合,那么就可以完成通路,访问所有的边。
     99              else
    100              printf("NO\n");
    101       }
    102      return 0;                             
    103   }
  • 相关阅读:
    编译安装dropbear
    ssh的相关实验
    通过ssh协议实现用户key认证登录
    cobbler实现自动安装
    Centos 6 PXE安装
    Centos 7 PXE一键安装
    openssl命令
    实现CA证书创建及客户端申请证书
    android 动画
    BottomSheetBehavior 结合CoordinatorLayout实现底部栏
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2667103.html
Copyright © 2011-2022 走看看