所有评测用例满足:1 ≤ n ≤ 10000,n-1 ≤ m ≤ 100000。
说实话第一眼看到这个题就蒙了,完全不会,就去搜了题解,看看思路也是极好的,这是求是否有欧拉路径,若有,则打印路径,若没有,就输出-1,普及小知识的时间start:
欧拉路径:寻找一条只通过每条边一次的路径
(1)源点和汇点不为同一点
(2)源点与汇点的度数为奇数外,其余的点为偶数
(3)判断奇数度数点个数是否为0或者2,若奇数点个数为2,当起点为偶数的时候,就不是欧拉函数了
欧拉回路:起点和终点是同一点(当所有点是偶数,可以任意得到一条欧拉回路)
无向图:每个顶点的入度是偶数,则存在欧拉回路
有向图:每个顶点的入度和出度相等
下面就贴出一个博客的代码:
#include<iostream> #include<stack> #include<vector> #include<algorithm> #include<cstdio> using namespace std; const int maxn=10005; stack<int> st; vector<int> vec[maxn]; bool map[maxn][maxn];//改成int,就不对了 int vis[maxn]; int cp[maxn]; int n,m; void pd(int a) { cp[a]=1; vector<int>::iterator it; for(it=vec[a].begin();it!=vec[a].end();it++) { if(!cp[*it]) pd(*it); } } void dfs(int a) { vector<int>::iterator it; for(it=vec[a].begin();it!=vec[a].end();it++) { if(!map[a][*it]) { map[a][*it]=1; map[*it][a]=1; dfs(*it); st.push(*it); } } } void prt() { st.push(1); while(!st.empty()) { //printf("%d ",st.top()); int ss=st.top(); st.pop(); printf("%d ",ss); } } int main() { int num=0; //memset(cp,0,sizeof(cp)); //memset(vis,0,sizeof(vis)); //memset(map,0,sizeof(map)); for(int i=0;i<maxn;++i) { cp[i]=vis[i]=0; } scanf("%d %d",&n,&m); int a,b; for(int i=0;i<m;++i) { scanf("%d %d",&a,&b); vec[a].push_back(b); vec[b].push_back(a); vis[a]++; vis[b]++; } int flag=0; pd(1); for(int i=1;i<=n;++i) { if(cp[i]==0) flag=1; else break; } if(flag) printf("-1\n"); else { for(int i=1;i<=n;++i) { sort(vec[i].begin(),vec[i].end()); if(vis[i]%2==1) ++num; } if(num==0||num==2) { if(num==2) { if(vis[1]%2==1) { dfs(1); prt(); } else printf("-1\n"); } else { dfs(1); prt(); } } else { printf("-1\n"); } } return 0; }
再贴出我认识的一个大神写的代码,仅仅用了70+MB,说白了这个题关键是改容器,用<set>,<stack>,<hash>,方可达到减少内存,,,但速度越来越慢。。。。。。
废话少说,贴代码:
#include <stdio.h> #include <set> using namespace std; bool map[50005000], connect[10005]; int n, m, mem[1000005]; set<int> edge[10005]; class Stack { public: int p; Stack() { p = 0; } void push(int x) { mem[p++] = x; } void print() { printf("1"); for(int i = p - 1; i >= 0; --i) printf(" %d", mem[i]); } } stack; int pos(int x, int y) { if (x > y) return y + ((x * (x - 1)) >> 1); else return x + ((y * (y - 1)) >> 1); } void pd(int x) { connect[x] = 1; for (set<int>::iterator it = edge[x].begin(); it != edge[x].end(); ++it) if(!connect[*it]) pd(*it); } void dfs(int x) { for (set<int>::iterator it = edge[x].begin(); it != edge[x].end(); ++it) if (!map[pos(x, *it)]) { map[pos(x, *it)] = 1; dfs(*it); stack.push(*it); } } int main() { if(fopen("in.txt","r")) freopen("in.txt","r",stdin); scanf("%d %d", &n, &m); int x, y; for (int i = 0; i < m; ++i) { scanf("%d %d", &x, &y); edge[x].insert(y); edge[y].insert(x); mem[x] = !mem[x]; mem[y] = !mem[y]; } pd(1); for (int i = 1; i <= n; ++i) if (!connect[i]) { printf("-1\n"); return 0; } int o = 0; for (int i = 1; i <= n; ++i) o += mem[i]; if ((o == 2 && mem[1] == 1) || o == 0) { dfs(1); stack.print(); } else { printf("-1\n"); } return 0; }