ZJU2103 Marco Popo the Traveler - 欧拉图 深度优先搜索

题目大意:

n个城市之间有h条道路(n<10,h<20),每条道路都被涂成一种颜色。当汽车的轮胎颜色和道路颜色一致时,才能在道路上行驶。马可波罗从任意城市出发,初始时轮胎可为任意颜色。他遍历每条道路仅一次,问最少需要换多少次轮胎。

分析:

典型的欧拉通路问题,即一笔画问题。用深度优先搜索就好。

要注意的是需要考虑道路不连通的情况。

 

/*
ZJU2103 Marco Popo the Traveler
*/

#include <stdio.h>
#include <memory.h>

#define clr(a) memset(a,0,sizeof(a))

#define N 15
#define H 25

int n,m,col;
int min;

int a[N][N];
int e[N][N];
int d[N];

void search(int i,int color,int count,int deep)
{
    if(deep==0){
        if(count-1<min) min=count-1;
        return;
    }

    //next
    int j;
    for(j=0;j<n;j++){
        if(a[i][j]&&!e[i][j]){
            e[i][j]=e[j][i]=1;
            search(j,a[i][j],count+(color!=a[i][j]),deep-1);
            e[i][j]=e[j][i]=0;
        }
    }
}

int main()
{
   
    while(scanf("%d%d%d",&n,&col,&m),n+col+m)
    {
        //init
        clr(a);
        clr(e);
        clr(d);
        min=m;
       
        //input
        int i,j,c,k;
        for(k=0;k<m;k++){
            scanf("%d%d%d",&i,&j,&c);
            a[i][j]=a[j][i]=c+1;
            d[i]++;
            d[j]++;
        }
       
        //pre process
        int count_odd=0;
        for(i=0;i<n;i++){
            if(d[i]%2) count_odd++;
        }
       
        if(count_odd>2){
            puts("No");
            continue;
        }
       
        //work
        if(count_odd==2){
            for(i=0;i<n;i++)
                if(d[i]%2){
                    clr(e);
                    search(i,0,0,m);
                }
        }
        else{
            for(i=0;i<n;i++){
                clr(e);
                search(i,0,0,m);
            }
        }
       
        //output
        if(min==m) puts("No");
        else printf("%d/n",min);

    }
   
    return 0;
}

 

你可能感兴趣的:(c,search,ini)