poj 1300 欧拉回路、通路 解题报告

mac2022-06-30  26

最近学了一些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   }

 

转载于:https://www.cnblogs.com/nuoyan2010/archive/2012/09/01/2667103.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)