CCF 201512-4 送货(欧拉路径+字典序最小)

来源:互联网 发布:南京擎天科技知乎 编辑:程序博客网 时间:2024/04/29 20:29
题目地址: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 debuusing 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;}




0 0
原创粉丝点击