1. 程式人生 > >UOJ 117 歐拉回路(套圈法+歐拉回路路徑輸出+騷操作)

UOJ 117 歐拉回路(套圈法+歐拉回路路徑輸出+騷操作)

height int ima 標記 圖片 style 技術分享 () targe

題目鏈接:http://uoj.ac/problem/117

題目大意:

技術分享圖片

解題思路:先判斷度數:

     若G為有向圖,歐拉回路的點的出度等於入度。

     若G為無向圖,歐拉回路的點的度數位偶數。

     然後判斷連通性,並且輸出路徑需要用套圈法(其實我也不是很懂)。

     還學了一些騷操作:

     ①用鏈式前向星存圖,如果是有向圖,那idx隔兩個存一條邊,如果是無向圖則idx隔一個存一條邊,且idx從2開始。這樣寫的作用就是在尋無向圖路徑時可以良好地標記,比如第一條無向邊裏idx=2、3分別對應一條正反邊,2和3除2都對應1,那麽我們只需標記vis[1]就好了,因為歐拉回路只需要用到其中一條邊。有向圖因為要防止兩條當一條用,所以要idx要隔2存一條邊。

     ②在遍歷鄰接表時j加一個引用,快了超多。

代碼:

 1 #include<iostream>
 2 #include<stack>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=1e5+5;
 8 const int M=2e5+5;
 9 
10 struct node{
11     int to,next,w;
12 }edge[M*2
]; 13 14 int n,m,idx,cnt; 15 int head[N],in_deg[N],out_deg[N],ans[N]; 16 bool vis[M*2]; 17 18 void init(){ 19 idx=2; 20 memset(vis,false,sizeof(vis)); 21 memset(head,0,sizeof(head)); 22 memset(in_deg,0,sizeof(in_deg)); 23 memset(out_deg,0,sizeof(out_deg)); 24 } 25 26
void addedge(int u,int v,int w){ 27 edge[idx].to=v; 28 edge[idx].next=head[u]; 29 edge[idx].w=w; 30 head[u]=idx++; 31 } 32 33 //傳說中的套圈法,輸出歐拉回路路徑 34 void dfs(int u){ 35 //這個引用好神奇啊,速度快了好多,學習了0 0 36 //好像類似於網絡流的cur優化(沒學過網路流,瞎說的) 37 //然後關於idx的處理也很巧妙 38 for(int &j=head[u];j;j=edge[j].next){ 39 node t=edge[j]; 40 if(!vis[j>>1]){ 41 vis[j>>1]=true; 42 dfs(t.to); 43 ans[++cnt]=t.w; 44 } 45 } 46 } 47 48 int main(){ 49 int t; 50 scanf("%d%d%d",&t,&n,&m); 51 init(); 52 int a,b; 53 for(int i=1;i<=m;i++){ 54 scanf("%d%d",&a,&b); 55 addedge(a,b,i); 56 in_deg[b]++; 57 out_deg[a]++; 58 if(t==1) 59 addedge(b,a,-i); 60 else 61 idx++; 62 } 63 bool flag=true; 64 if(t==1){ 65 for(int i=1;i<=n;i++){ 66 if((in_deg[i]+out_deg[i])%2){ 67 flag=false; 68 break; 69 } 70 } 71 } 72 else{ 73 for(int i=1;i<=n;i++){ 74 if(in_deg[i]!=out_deg[i]){ 75 flag=false; 76 break; 77 } 78 } 79 } 80 if(flag){ 81 dfs(a); 82 if(cnt!=m) 83 puts("NO"); 84 else{ 85 puts("YES"); 86 for(int i=cnt;i>=1;i--){ 87 if(i==1) 88 printf("%d\n",ans[i]); 89 else 90 printf("%d ",ans[i]); 91 } 92 } 93 } 94 else 95 puts("NO"); 96 return 0; 97 }

UOJ 117 歐拉回路(套圈法+歐拉回路路徑輸出+騷操作)