UVa 10596 - Morning Walk, 赤裸裸的欧拉回路

10596 - Morning Walk 3791
37.43%
1073
89.84%

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=105&page=show_problem&problem=1537


题目类型: 欧拉回路, 并查集, dfs


题目:

Kamal is a Motashota guy. He has got a new job in Chittagong. So, he has moved to Chittagong from Dinajpur. He was getting fatter in Dinajpur as he had no work in his hand there. So, moving to Chittagong has turned to be a blessing for him. Every morning he takes a walk through the hilly roads of charming city Chittagong. He is enjoying this city very much. There are so many roads in Chittagongand every morning he takes different paths for his walking. But while choosing a path he makes sure he does not visit a road twice not even in his way back home. An intersection point of a road is not considered as the part of the road. In a sunny morning, he was thinking about how it would be if he could visit all the roads of the city in a single walk. Your task is to help Kamal in determining whether it is possible for him or not.


题目大意:

Kamal每天早上都要从家里走到Chittagongand这个地方。 从家里到Chittagongand有很多条路, 他每天早上都要先选择好一条路线, 这条路线从家里走到Chittagongand,在从Chittagongand走回家里。 这条路线不能重复地经过同一条路。 两个地点间可能会有多条路。 比如多次出现了从A到B的路线,  那么表示每次出现的都是不同的路


分析与总结:

这题就是赤裸裸的欧拉回路。UVa 10054 - The Necklace   UVa 10129 - Play on Words    这两篇讲得较详细。 不再累赘


1. 欧拉回路+DFS

#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
int vis[210],N, M, G[210][210], inDegree[210], outDegree[210];

void dfs(int v)         //深度优先遍历  
{  
    vis[v]=true;  
    for(int i=0;i<N;i++)  
    {  
        if(!vis[i] && G[v][i])  
        {  
            dfs(i);  
        }  
    }  
}  

int main(){
#ifdef LOCAL
    freopen("input.txt","r",stdin);
#endif
    while(~scanf("%d %d",&N, &M)){
        memset(G, 0, sizeof(G));
        int a,b;
        memset(vis, 0, sizeof(vis));
        for(int i=0; i<M; ++i){
            scanf("%d %d",&a,&b);
            G[a][b] = G[b][a] = 1;
            ++vis[a]; 
            ++vis[b];
        }
        
        int cnt = 0;
        for(int i=0; i<N; ++i){
            if(vis[i]%2==1){
                ++cnt;
                break;
            }
        }
        memset(vis, 0, sizeof(vis));
        if(cnt || M<2) printf("Not Possible\n");
        else{
            dfs(0);
            bool flag = true;
            for(int i=0; i<N; ++i) {
                if(!vis[i]) flag = false;
            }
            if(flag)printf("Possible\n");
            else printf("Not Possible\n");
        }
    
    }
    return 0;
}

2,欧拉回路+并查集

#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
int vis[210],N, M, G[210][210], inDegree[210], outDegree[210], f[210];

void init()   //并查集判断是否是一个连通图  
{  
    int i;  
    for(i=0;i<N;i++)  
        f[i]=i;  
}  
int find(int x)  
{  
    int r=x;  
    while(f[r]!=r)  
    r=f[r];  
    f[x]=r;  
    return r;  
}  
void Union(int x,int y)  
{  
    int fx,fy;  
    fx=find(x);  
    fy=find(y);  
    if(fx!=fy)  
    f[fx]=fy;  
}  

int main(){
#ifdef LOCAL
    freopen("input.txt","r",stdin);
#endif
    while(~scanf("%d %d",&N, &M) && N){
        memset(G, 0, sizeof(G));
        int a,b;
        init();
        memset(vis, 0, sizeof(vis));
        for(int i=0; i<M; ++i){
            scanf("%d %d",&a,&b);
            ++G[a][b];
            ++G[b][a];
            ++vis[a];
            ++vis[b];
            Union(a,b);
        }
        
        int ans=0;
        for(int i=0; i<N; ++i) if(f[i]==i) ++ans;
        
        if(ans==1 && M>=2){
            int cnt = 0;
            for(int i=0; i<N; ++i){
                if(vis[i]%2==1){
                    ++cnt;
                    break;
                }
            }
            if(cnt) printf("Not Possible\n");
            else printf("Possible\n");
        }
        else
            printf("Not Possible\n"); 
    }
    return 0;
}


——      生命的意义,在于赋予它意义。 

                   原创  http://blog.csdn.net/shuangde800  , By   D_Double










你可能感兴趣的:(ini,Path,IM)