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 }
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 }
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 }
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 }