sgu 101 Domino (欧拉路)
2014-10-04 19:22
281 查看
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=101
思路: 最裸的欧拉路的题目 把骨牌的每一面当成点 每一张骨牌的两面都建一条无向边 求出此图的一条欧拉路即可。
在此总结一下欧拉路的知识:
无向图的欧拉路的存在判定: 为连通图 度数为奇数的点的个数为0 or 2
欧拉路的输出:
1.度数为奇数的点的个数为0(此图存在欧拉回路) 任选一点 用dfs入栈记录 最后再倒着输出即可
2.度数为奇数的点的个数为2(非欧拉图) 选出度数为奇数的点 然后再进行dfs
代码中并查集的判联通部分可以用dfs代替
code:
思路: 最裸的欧拉路的题目 把骨牌的每一面当成点 每一张骨牌的两面都建一条无向边 求出此图的一条欧拉路即可。
在此总结一下欧拉路的知识:
无向图的欧拉路的存在判定: 为连通图 度数为奇数的点的个数为0 or 2
欧拉路的输出:
1.度数为奇数的点的个数为0(此图存在欧拉回路) 任选一点 用dfs入栈记录 最后再倒着输出即可
2.度数为奇数的点的个数为2(非欧拉图) 选出度数为奇数的点 然后再进行dfs
代码中并查集的判联通部分可以用dfs代替
code:
#include <cstdio> #include <algorithm> #include <iostream> #include <cstring> using namespace std; const int maxn=10500; const int maxe=10500; struct edge { int to,next,flag; } G[maxe]; int head[maxn],si,du[maxn],way[maxe]; int cnt,nn; bool vis[10]; void add_edge(int s,int t) { G[si].flag=true; G[si].to=t; G[si].next=head[s]; head[s]=si++; G[si].flag=true; G[si].to=s; G[si].next=head[t]; head[t]=si++; } int par[maxn],num[maxn]; void init(int n_) { for(int i=0;i<=n_;i++){ par[i]=i; num[i]=1; } } int Find(int x) { if(x==par[x]) return x; return par[x]=Find(par[x]); } void unite(int x,int y) { x=Find(x); y=Find(y); if(num[x]<num[y]){ par[x]=y; num[y]+=num[x]; } else{ par[y]=x; num[x]+=num[y]; } } bool same(int x,int y) { return Find(x)==Find(y); } void dfs(int vv,int tt) { for(int i=head[vv];i!=-1;i=G[i].next){ if(!G[i].flag) continue; G[i].flag=G[i^1].flag=false; dfs(G[i].to,i); } if(tt!=-1) way[cnt++]=tt; } void output(int kk) { cnt=0; if(kk==0){ for(int i=0;i<=6;i++){ if(!vis[i]) continue; dfs(i,-1); break; } } else{ for(int i=0;i<=6;i++){ if(!vis[i]) continue; if(du[i]%2!=0){ dfs(i,-1); break; } } } for(int i=cnt-1;i>=0;i--){ if(way[i]%2) printf("%d -\n",way[i]/2+1); else printf("%d +\n",way[i]/2+1); } } int main() { int N,s,t,cnt1,cnt2,nn; bool mark; while(scanf("%d",&N)!=EOF){ init(N); nn=0; memset(vis,0,sizeof(vis)); memset(du,0,sizeof(du)); memset(head,-1,sizeof(head)); si=0; for(int kk=0;kk<N;kk++){ scanf("%d%d",&s,&t); add_edge(s,t); du[s]++; du[t]++; if(!same(s,t)) unite(s,t); vis[s]=vis[t]=true; } for(int i=0;i<=6;i++) if(vis[i]) nn++; mark=0; for(int i=0;i<=6;i++){ if(!vis[i]) continue; if(num[Find(i)]!=nn){ printf("No solution\n"); mark=1; } break; } if(mark==1) continue; cnt1=cnt2=0; for(int i=0;i<=6;i++){ if(!vis[i]) continue; if(du[i]%2==0) cnt1++; else cnt2++; } if(cnt2==0) output(0); else if(cnt2==2) output(1); else printf("No solution\n"); } }
相关文章推荐
- SGU101 - Domino(欧拉路)
- SGU 101 Domino(欧拉图)
- SGU 101 Domino【欧拉路径】
- sgu 101 Domino 解题报告及测试数据
- SGU 101 Domino【欧拉路径】
- sgu-101-Domino
- SGU 101 domino
- [SGU 101] Domino [欧拉回路]
- SGU-101 Domino
- SGU101 Domino 留坑
- sgu 101 Domino【输出欧拉路径】
- sgu 101 Domino 欧拉路径+DFS
- SGU 101 Domino
- SGU 101 Domino 里程碑2——开始刷sgu!
- sgu 101/poj 2230欧拉路
- SGU 101 Domino(无向图的欧拉路径)
- SGU101 - Domino
- sgu 101 Domino 欧拉通路
- SGU 101 Domino (欧拉路径 并查集)
- SGU 101 Domino 题解