Gym 100851K

Problem King's Inspection

题目大意

  给一张n个点m条边的无向图,问是否存在一条欧拉回路。

  n<=10^5, 0<=m<=n+20。

解题分析

  注意到数据范围m<=n+20,可以想象若存在一条欧拉回路,那么图的形状必定是一条长链再加上20条边。

  将连续的一段入度和出度均为0的点缩成一个点,之后暴力跑欧拉回路就行了。

参考程序

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <string>
  8 #include <vector>
  9 #include <cstdio>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <cassert>
 13 #include <iostream>
 14 #include <algorithm>
 15 #pragma comment(linker,"/STACK:102400000,102400000")
 16 using namespace std;
 17 
 18 #define V 1000008            
 19 #define E 2000008   
 20 #define LL long long
 21 #define lson l,m,rt<<1
 22 #define rson m+1,r,rt<<1|1 
 23 #define clr(x,v) memset(x,v,sizeof(x));
 24 #define bitcnt(x) __builtin_popcount(x)
 25 #define rep(x,y,z) for (int x=y;x<=z;x++)
 26 #define repd(x,y,z) for (int x=y;x>=z;x--)
 27 const int mo  = 1000000007;
 28 const int inf = 0x3f3f3f3f;
 29 const int INF = 2000000000;
 30 /**************************************************************************/ 
 31 
 32 int lt[V],sum,indeg[V],outdeg[V],vis[V],cnt,nt[V],LT[V],SUM,fa[V],succ[V];
 33 
 34 struct line{
 35     int u,v,nt,flag;
 36 }eg[E],EG[E];
 37 
 38 void add(int u,int v){
 39     eg[++sum]=(line){u,v,lt[u],1};
 40     lt[u]=sum;
 41     indeg[v]++; outdeg[u]++; 
 42 }
 43 void ADD(int u,int v){
 44     EG[++SUM]=(line){u,v,LT[u],1};
 45     LT[u]=SUM; 
 46 }
 47 int n,m;
 48 bool check(int u){
 49     return indeg[u]==1 && outdeg[u]==1;
 50 }
 51 void dfs(int u){
 52     vis[u]=1; cnt++;
 53     for (int i=lt[u];i;i=eg[i].nt){
 54         int v=eg[i].v;
 55         if (vis[v]) continue;
 56         if (check(v) && check(u) && eg[lt[v]].v!=u){
 57             nt[u]=v; fa[v]=u;
 58             eg[i].flag=0;
 59         }
 60         dfs(v);
 61     }
 62 }           
 63 
 64 bool find(int u,int num){
 65     if (u==1 && num==cnt) return 1;
 66     if (u==1 && num!=0) return 0;
 67     for (int i=LT[u];i;i=EG[i].nt){
 68         int v=EG[i].v;
 69         if (fa[v]) continue;
 70         fa[v]=u; succ[u]=v;
 71         if (find(v,num+1)) return 1;
 72         fa[v]=0;
 73     }
 74     return 0;
 75 }
 76 
 77 int main(){
 78     freopen("king.in","r",stdin);
 79     freopen("king.out","w",stdout);
 80     scanf("%d%d",&n,&m);
 81     rep(i,1,m){
 82         int u,v;
 83         scanf("%d%d",&u,&v);
 84         add(u,v);
 85     }
 86     add(1,1);
 87     clr(vis,0); cnt=0;
 88     dfs(1);
 89     if (cnt!=n) { printf("There is no route, Karl!
"); return 0; }
 90     cnt=n;
 91     clr(vis,0);
 92     rep(i,1,sum)
 93         if (eg[i].flag) ADD(eg[i].u,eg[i].v);
 94         else
 95         {
 96             int l=eg[i].u,r=eg[i].v;
 97             if (vis[l]||vis[r]) continue;
 98             while (fa[l]) l=fa[l];
 99             while (nt[r]) r=nt[r];
100             r=eg[lt[r]].v;
101             ADD(l,r);
102             int x=l;
103             while (nt[x])
104             {
105                 x=nt[x];
106                 cnt--;
107                 vis[x]=1;
108             }
109         }
110     clr(fa,0);
111     if (!find(1,0)) { printf("There is no route, Karl!
"); return 0; }
112     int u=1;
113     while (1){
114         printf("%d ",u);
115         int uu=nt[u];
116         while (uu)
117         {
118             printf("%d ",uu);
119             uu=nt[uu];
120         }
121         u=succ[u];
122         if (u==1) break;
123     }
124     printf("1
");
125 }
View Code
原文地址:https://www.cnblogs.com/rpSebastian/p/5824148.html