题目地址:http://115.28.138.223/view.page?gpid=T34
思路:
图连通条件下
有向图回路:每个点入度=出度
有向图路径:每个点入度=出度的或只有两个点a、b,a的入-出=1,b的出-入=1
无向图回路:每个点度为偶数
无向图路径:每个点度为偶数或只有两个点的度数为奇数
注意:字典序最小求法(按照两点编号和从大到小排序,建边)。
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const int maxn=1e4+50;
const int maxm=2e5+50;
struct Edge
{
int to,nxt,v;
};
struct Node
{
int x,y,sum;
};
int v[maxn];
vector<int> ans;
Node p[maxm];
int n,m,tot=0,nt;
Edge edge[maxm];
int d[maxn],head[maxn];
int cmp(Node a,Node b)
{
return a.sum>b.sum;
}
void addedge(int x,int y)
{
edge[tot].to=y,edge[tot].nxt=head[x],head[x]=tot++;
edge[tot].to=x,edge[tot].nxt=head[y],head[y]=tot++;
}
void solve(int u)
{
v[u]=1;
for(int i=head[u]; i!=-1; i=edge[i].nxt)
{
if(!edge[i].v&&!edge[i^1].v)
{
nt=edge[i].to;
edge[i].v=1;
edge[i^1].v=1;
solve(nt);
}
}
ans.push_back(u);
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif // debug
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].sum=p[i].x+p[i].y;
d[p[i].x]++,d[p[i].y]++;
}
sort(p,p+m,cmp);
for(int i=0; i<m; i++)
addedge(p[i].x,p[i].y);
int num=0;
for(int i=1; i<=n; i++)
if(d[i]&1) num++;
solve(1);
int flag=0;
for(int i=1; i<=n; i++)
if(!v[i]) flag=1;
if(!(num==0||num==2)||flag) printf("-1\n");
else
{
for(int i=ans.size()-1; i>0;i--)
printf("%d ",ans[i]);
printf("%d\n",ans[0]);
}
return 0;
}