hdu5348(歐拉回路+尤拉路徑)
阿新 • • 發佈:2019-02-03
題意:n個點m條邊的無向圖,問是否滿足將所有邊變為有向後,每個點入度和出度的點不超過1
程式碼:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; struct node{ int to,next,cost; }G[1000005]; int cnt,sign,deg[200005],head[200005]; void addedge(int u,int v){ G[cnt].to=v; G[cnt].cost=0; G[cnt].next=head[u]; head[u]=cnt++; } void dfs(int s){ int i,tmp,flag; if(sign) return; for(i=head[s];i!=-1;i=G[i].next){ if(sign) //剪枝 return; tmp=G[i].to; flag=G[i].cost^G[i^1].cost; //判斷這條無向邊是否走過 if(flag) continue; head[s]=G[i].next; //走過的邊就不再走了 G[i].cost=1; if(deg[tmp]){ //遇到奇度點就不再搜尋 sign=1; deg[tmp]=0; return; } if(!sign) dfs(tmp); } return; } int main(){ //需要知道三個性質 int n,m,t,i,j,u,v; //1.一個圖奇度點有偶數個 scanf("%d",&t); //2.只含有兩個奇度點的無向圖含有尤拉路徑 while(t--){ //3.不含奇度點的無向圖含有歐拉回路 cnt=0; //根據這三個性質可以得出一個圖必定可以拆成一個 scanf("%d%d",&n,&m); //歐拉回路和許多尤拉路徑,因此奇度點兩兩配對 for(i=1;i<=n;i++) deg[i]=0,head[i]=-1; for(i=0;i<m;i++){ scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); deg[u]^=1,deg[v]^=1; } for(i=1;i<=n;i++){ if(deg[i]){ //奇度點進行尤拉路徑的搜尋 sign=deg[i]=0; dfs(i); } } sign=0; for(i=1;i<=n;i++) if(head[i]!=-1) //不是孤立點的點i進行歐拉回路的搜尋 dfs(i); for(i=0;i<cnt;i+=2) printf("%d\n",G[i].cost); } return 0; }