蓝书3.7 欧拉回路

T1 欧拉回路 hdu 1878

题目大意:

判断是否存在欧拉回路

思路:

一个无向图存在欧拉回路的条件为所有点的度为偶数 且图联通

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 10100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,m,fa[MAXN],fst[MAXN],nxt[MAXN<<3],to[MAXN<<3],d[MAXN],cnt;
21 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,d[v]++;}
22 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
23 void merge(int a,int b) {int f1=find(a),f2=find(b);if(f1!=f2) fa[f1]=f2;}
24 int main()
25 {
26     while(1)
27     {
28         n=read();if(!n) break;
29         m=read();int a,b;
30         memset(d,0,sizeof(d));memset(fst,0,sizeof(fst));cnt=0;
31         for(int i=1;i<=n;i++) fa[i]=i;
32         while(m--) {a=read(),b=read();add(a,b);add(b,a);merge(a,b);}
33         for(int i=1;i<n;i++) if(find(i)!=find(i+1)) {puts("0");goto ed;}
34         for(int i=1;i<=n;i++) if(d[i]&1) {puts("0");goto ed;}
35         puts("1");
36         ed:;
37     }
38 }
View Code

T2 Ant Trip hdu 3018

题目大意:

最少次一笔画可以遍历所有边

思路:

独立的点对答案没有贡献

每个联通块如果奇数度的点等于0 ans+1

大于0 ans+=奇数点数/2

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 100100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,m,fa[MAXN],fst[MAXN],nxt[MAXN<<2],to[MAXN<<2],d[MAXN],cnt,ans,sz[MAXN],k[MAXN];
21 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,d[v]++;}
22 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
23 void merge(int a,int b) {int f1=find(a),f2=find(b);if(f1!=f2) fa[f1]=f2;sz[f2]+=sz[f1];}
24 int main()
25 {
26     int a,b;
27     while(scanf("%d%d",&n,&m)==2)
28     {
29         memset(d,0,sizeof(d));memset(fst,0,sizeof(fst));
30         memset(k,0,sizeof(k));memset(sz,0,sizeof(sz));ans=cnt=0;
31         for(int i=1;i<=n;i++) fa[i]=i;
32         while(m--) {a=read(),b=read();add(a,b);add(b,a);merge(a,b);}
33         for(int i=1;i<=n;i++) sz[find(i)]++;
34         for(int i=1;i<=n;i++) if(d[i]&1) k[find(i)]++;
35         for(int i=1;i<=n;i++) if(fa[i]==i&&sz[i]>1) ans+=k[i]?k[i]>>1:1;
36         printf("%d
",ans);
37     }
38 }
View Code

T3 John‘s Trip poj 1041

题目大意:

求图中是否存在欧拉回路 并求出任意一个欧拉回路

思路:

判欧拉回路就用度数判一下

然后dfs就行了

但是改变了dfs和把边加入栈的顺序 就wa了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 5010
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int rt,n,m,to[MAXN],e[45][MAXN],d[MAXN],cnt,st[MAXN],top,vis[MAXN];
21 void dfs(int x)
22 {
23     for(int i=1;i<=cnt;i++)
24         if(!vis[i]&&e[x][i]) {vis[i]=1;dfs(e[x][i]);st[++top]=i;}
25 }
26 void solve()
27 {
28     for(int i=1;i<=45;i++) if(d[i]&1) {puts("Round trip does not exist.");return;}
29     dfs(rt);
30     for(int i=top;i>1;i--) printf("%d ",st[i]);
31     printf("%d
",st[1]);
32 }
33 int main()
34 {
35     int a,b,c;rt;
36     while(scanf("%d%d",&a,&b))
37     {
38         if(!a&&!b) break;rt=min(a,b),c=read(),e[a][c]=b,e[b][c]=a,d[a]++,d[b]++,cnt++;
39         while(scanf("%d%d",&a,&b))
40             {if(!a&&!b) {solve();break;}c=read(),e[a][c]=b,e[b][c]=a,d[a]++,d[b]++,cnt++;}
41         memset(e,0,sizeof(e));memset(d,0,sizeof(d));cnt=top=0;
42         memset(vis,0,sizeof(vis));
43     }
44 }
View Code

T4 太鼓达人 bzoj 3033

题目大意:

给定k 求最长长度的01串

把这个串变成环 使这个环所有长度为k的子串互不相同 

输出这个串的最长长度 并输出字典序最小的串

思路:

可以发现有1<<k个不同的串

使用dfs搜索 爆搜能过的原因是因为原图是一个欧拉图

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 6010
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,t,vis[MAXN],ans[MAXN];
21 int dfs(int x,int cnt)
22 {
23     if(vis[x]) return 0;if(cnt==t) return 1;
24     ans[cnt]=x&1,vis[x]=1;
25     if(dfs((x<<1)%t,cnt+1)) return 1;
26     if(dfs((x<<1|1)%t,cnt+1)) return 1;
27     vis[x]=0;return 0;
28 }
29 int main()
30 {
31     n=read();printf("%d ",t=1<<n);
32     for(int i=1;i<n;i++) printf("0");
33     dfs(0,1);for(int i=1;i<=t-n+1;i++) printf("%d",ans[i]);
34 }
View Code
原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9378234.html