歐拉回路相關定理(相關定義和證實請參見其餘資料):ios
1.歐拉回路網絡
(1)有向圖:全部點的出度都等於入度爲該圖爲歐拉圖(存在歐拉回路)的充要條件。優化
(2)無向圖:全部點的度都爲偶數爲該圖爲歐拉圖(存在歐拉回路)的充要條件。spa
2.歐拉通路3d
(1)有向圖:除兩點(其中一點出度+1==入度,另外一點入度+1==出度)另外點出度都等於入度爲該圖爲半歐拉圖(存在歐拉通路)的充要條件。code
(2)無向圖:除兩點(兩點度都爲奇數)另外點的度都爲偶數爲該圖爲半歐拉圖(存在歐拉通路)的充要條件。blog
以上定理用於判斷是否爲存在歐拉回路或者通路string
接下來是兩個推論:it
嗯就是這樣··再回到這道題上,一道很裸地模版題···然而被uoj大佬的數據教作人··io
注意斷定重邊否則就會超時·····用相似於網絡流的cur來優化(具體見代碼)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=1e5+5; const int M=5e5+5; int first[N],go[M*2],next[M*2],tot=0; int n,m,T,ru[N],chu[N],stack[M*2],cnt; bool visit[M]; inline void comb(int a,int b) { next[++tot]=first[a],first[a]=tot,go[tot]=b; } inline void dfs1(int u) { for(int &e=first[u];e;e=next[e]) { if(!visit[e]) { visit[e]=true; if(e%2==1) visit[e+1]=true; else visit[e-1]=true; int t=e; dfs1(go[e]); stack[++cnt]=t; } } } inline void dfs2(int u) { for(int &e=first[u];e;e=next[e]) { if(!visit[e]) { visit[e]=true; int t=e; dfs2(go[e]); stack[++cnt]=t; } } } int main() { //freopen("a.in","r",stdin); scanf("%d",&T); int a,b; scanf("%d%d",&n,&m); if(T==1) //無向圖狀況 { for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); comb(a,b); comb(b,a); ru[b]++; chu[a]++; } for(int i=1;i<=n;i++) if((ru[i]+chu[i])%2==1) { cout<<"NO"<<endl; return 0; } for(int i=1;i<=n;i++) { if(first[i]) { dfs1(i); break; } } if(cnt!=m) { cout<<"NO"<<endl; return 0; } cout<<"YES"<<endl; for(int i=cnt;i>=1;i--) { if(stack[i]%2==1) cout<<(stack[i]+1)/2<<" "; else cout<<stack[i]/2*(-1)<<" "; } return 0; } else { for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); comb(a,b); ru[b]++; chu[a]++; } for(int i=1;i<=n;i++) if(ru[i]!=chu[i]) { cout<<"NO"<<endl; return 0; } for(int i=1;i<=n;i++) { if(first[i]) { dfs2(i); break; } } if(cnt!=m) { cout<<"NO"<<endl; return 0; } cout<<"YES"<<endl; for(int i=cnt;i>=1;i--) cout<<stack[i]<<" "; return 0; } }