記性不好 寫上來當做mark= =。。。
Time Limit: 1000 MS Memory Limit: 256 M
給出一幅n個點,m條邊的圖,分別判斷該圖是無向圖和有向圖條件下,是否存在歐拉通路。
輸入
輸入包含多組數據。第一行爲一個整數T(1 ≤ T ≤ 100),代表數據組數,對於每組數據: 第一行是兩個整數n和m( 1 ≤ n ≤ 500, 0 ≤ m ≤ n(n − 1)/2 ),分別代表圖上點的個數和邊的個數。
然後是m行,每行兩個整數ui和vi ( 1 ≤ ui, vi ≤ n, ui ≠ vi ),代表圖上的一條邊所連接的兩個點。輸入保證沒有重邊。
輸出
首先判斷:如果這幅圖是無向圖,是否存在歐拉通路;
其次判斷:如果這幅圖是有向圖,是否存在歐拉通路。
對於每個判斷,如果存在,輸出”Yes”,否則輸出”No”(不包括引號)。兩個判斷間用空格隔開。
樣例輸入
3
2 1
1 2
4 3
1 2
1 3
1 4
4 4
1 2
1 3
1 4
2 3
樣例輸出
Yes Yes
No No
Yes No
Hint
歐拉通路、歐拉回路、歐拉圖
無向圖:
1) 設 G 是連通無向圖,則稱經過 G 的每條邊一次並且僅一次的路徑爲歐拉通路;
2) 如果歐拉通路是迴路 (起點和終點是同一個頂點), 則稱此迴路爲歐拉回路 (Euler circuit);
3) 具有歐拉回路的無向圖 G 稱爲歐拉圖(Euler graph)。
有向圖:
1) 設 D 是有向圖, D 的基圖連通,則稱經過 D 的每條邊一次並且僅一次的有向路徑爲有向歐拉通路;
2) 如果有向歐拉通路是有向迴路,則稱此有向迴路爲有向歐拉回路(directed Euler circuit);
3) 具有有向歐拉回路的有向圖 D 稱爲有向歐拉圖(directed Euler graph)。
Extend
歐拉回路打印路徑算法:Fleury(佛羅萊)算法
Author
GooZy
題意:
分別判斷一個圖有向或無向時,是否有歐拉通路。
思路:
離散課講過七橋問題,如果一個無向圖要有歐拉通路的充分必要條件:奇數度的點只有兩個(因爲進入一個點,如果不是最後一個點或者第一個點的話 你肯定需要出來,所以其他點必須是偶數度點。)或者奇數度點爲0。
有向圖有歐拉回路的充要條件:
除兩個頂點外,其餘頂點的入度均等於出度,這兩個特殊的頂點中,一個頂點的入度比出度大1,另一個頂點的入度比出度小1。或者所有點的入度==出度。
wa點:
這個圖可能是不連通的。。
一個並查集可以搞定。。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int maxn=505;
int T,n,m,u,v;
int d[maxn],rd[maxn],cd[maxn];
int fa[maxn];
vector <int> G[maxn];
int find(int x){
int r=x;
while(fa[r]!=r){
r=fa[r];
}
int i=x,t;
while(fa[i]!=r){
t=fa[i];
fa[i]=r;
i=t;
}
return r;
}
int main(){
freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
memset(d,0,sizeof d);
memset(rd,0,sizeof rd);
memset(cd,0,sizeof cd);
int flag=0;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
scanf("%d %d",&u,&v);
d[u]++;
d[v]++;
rd[v]++;
cd[u]++;
int x=find(u);
int y=find(v);
fa[x]=y;
}
for(int i=2;i<=n;i++)
{
int r=find(i);
if(r!=find(1)){
flag=1;
break;
}
}
if(flag==1){
printf("No No\n");
continue;
}
int ans=0;
for(int i=1;i<=n;i++)
if(d[i] & 1) ans++;
if(ans==0 || ans==2) printf("Yes ");
else printf("No ");
vector <int> dd;
dd.clear();
for(int i=1;i<=n;i++)
if(rd[i]!=cd[i]){
dd.push_back(i);
}
//cout<<dd.size()<<endl;
if(dd.size()==0) {
printf("Yes\n");
continue;
}
if(dd.size()!=2) printf("No\n");
else {
u=dd[0];
v=dd[1];
int x1=rd[u]-cd[u];
int x2=rd[v]-cd[v];
if((x1==-1 && x2==1) || (x1==1 && x2==-1)) printf("Yes\n");
else printf("No\n");
}
}
}