[ZOJ]2103 Marco Popo the Traveler(欧拉回路/通路)

来源:互联网 发布:雨伞 知乎 编辑:程序博客网 时间:2024/06/10 04:27
#include<stdio.h>#include<stdlib.h>#include<string.h>#define INF 100000int n,c,h;//n:顶点(城市)个数//c:颜色个数//h:边个数int a[15][15];//图 int visit[15][15];//是否访问过边 int ans;int flag; void dfs(int v,int col,int cnt,int layer){int i;if(cnt>ans)return;if(layer==h){flag=1;if(cnt<ans)ans=cnt;return;}for(i=0;i<n;i++){if(a[i][v]&&!visit[i][v]){visit[i][v]=visit[v][i]=1;if(col!=a[i][v])dfs(i,a[i][v],cnt+1,layer+1);if(col==a[i][v])dfs(i,a[i][v],cnt,layer+1);visit[i][v]=visit[v][i]=0;}}}int main(){int i,j;int odd;//记录奇数度点的个数 int degree[30];//记录每个点的度 while(scanf("%d%d%d",&n,&c,&h),n&&c&&h){int connect=0;odd=0; flag=0; ans=INF;memset(a,0,sizeof(a));memset(degree,0,sizeof(degree));for(i=0;i<h;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);a[x][y]=a[y][x]=z+1;degree[x]++,degree[y]++;}for(i=0;i<n;i++){if(degree[i]%2)odd++;}        //奇数度的点为1或者大于2,不存在欧拉回路或欧拉通路 if(odd>2||odd==1){printf("No\n");continue;}//图只有一个点,最小颜色数为0 if(n==1){printf("0\n");continue;}//有两个奇数度的点,可能存在欧拉通路,因为图可能不连通 if(odd==2){for(i=0;i<n;i++){if(degree[i]%2){//从度数为奇数的点开始搜索 memset(visit,0,sizeof(visit));dfs(i,0,0,0);}}}//不存在度为奇数的点,可能存在欧拉回路,因为图可能不连通 else{for(i=0;i<n;i++){memset(visit,0,sizeof(visit));dfs(i,0,0,0);}}if(flag)printf("%d\n",ans-1);else printf("No\n");}return 0;}

0 0