#1176 : 歐拉路·一(歐拉通路的判定)

#1176 : 歐拉路·一

時間限制:10000ms
單點時限:1000ms
內存限制:256MB

描述
小Hi和小Ho最近在玩一個解密類的遊戲,他們需要控制角色在一片原始叢林裏面探險,收集道具,並找到最後的寶藏。現在他們控制的角色來到了一個很大的湖邊。湖上有N個小島(編號1…N),以及連接小島的M座木橋。每座木橋上各有一個寶箱,裏面似乎裝着什麼道具。

湖邊還有一個船伕,船伕告訴主角。他可以載着主角到任意一個島上,並且可以從任意一個島上再載着主角回到湖邊,但是主角只有一次來回的機會。同時船伕告訴主角,連接島嶼之間的木橋很脆弱,走過一次之後就會斷掉。

因爲不知道寶箱內有什麼道具,小Hi和小Ho覺得如果能把所有的道具收集齊肯定是最好的,那麼對於當前島嶼和木橋的情況,能否將所有道具收集齊呢?

舉個例子,比如一個由6個小島和8座橋組成的地圖:
在這裏插入圖片描述

主角可以先到達4號小島,然後按照4->1->2->4->5->6->3->2->5的順序到達5號小島,然後船伕到5號小島將主角接回湖邊。這樣主角就將所有橋上的道具都收集齊了。

提示:歐拉路的判定

輸入
第1行:2個正整數,N,M。分別表示島嶼數量和木橋數量。1≤N≤10,000,1≤M≤50,000

第2…M+1行:每行2個整數,u,v。表示有一座木橋連接着編號爲u和編號爲v的島嶼,兩個島之間可能有多座橋。1≤u,v≤N

輸出
第1行:1個字符串,如果能收集齊所有的道具輸出“Full”,否則輸出”Part”。

樣例輸入
6 8
1 2
1 4
2 4
2 5
2 3
3 6
4 5
5 6
樣例輸出
Full

涉及到的知識點:

  1. 歐拉通路定義:通過圖(無向圖或有向圖)中所有邊一次且僅一次 行遍所有的頂點通路稱作歐拉通路
  2. 歐拉回路的定義:通過圖中所有邊一次且僅一次行遍所有頂點迴路稱爲歐拉回路
  3. 歐拉圖:具有歐拉回路 的 圖稱爲歐拉圖
  4. 半歐拉圖:具有歐拉通路 的 圖稱爲半歐拉圖
  5. 規定平凡圖【1階零圖【一條邊也沒有】】爲歐拉圖。
  6. 定理1:無向圖歐拉圖 當且僅當它是連通圖沒有奇度頂點
  7. 定理2:無向圖半歐拉圖 當且僅當它是連通圖恰有2個奇度頂點

思路:

判斷歐拉通路:判斷它是否爲歐拉圖或半歐拉圖即可。

本題是無向圖,認真讀題,它給的一定是連通圖(所以無需判斷連通性),所以根據上述定理1和2只需要統計奇度頂點個數即可。

AC代碼:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e4+5;
int d[N];
/*
struct Edge
{
    int from;
    int to;
    int nxt;
}edge[N*5];
int head[N],idx;
bool vis[N];
int total;
void init()
{
    memset(head,-1,sizeof(head));
    idx = 0;
}
void add_edge(int from,int to)
{
    edge[idx].from = from;
    edge[idx].to = to;
    edge[idx].nxt = head[from];
    head[from] = idx++;
}
void dfs(int s)
{
    for(int i = head[s]; ~i; i = edge[i].nxt)
    {
        int to = edge[i].to;
        if(!vis[to])
        {
            vis[to] = true;
            total++;
            dfs(to);
        }
    }
}
*/
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    //init();
    while(m--)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        d[x]++;
        d[y]++;
        //add_edge(x,y);
        //add_edge(y,x);
    }
    int cnt = 0;
    for(int i = 1; i <= n; i++)
    {
        cnt += d[i] & 1;
    }
    bool flag = false;
    if(cnt == 0 || cnt == 2)
    {
        /*
        vis[1] = true;
        total = 1;
        dfs(1);*/
        flag = true;
    }
    flag?puts("Full"):puts("Part");
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章