码迷,mamicode.com
首页 > 其他好文 > 详细

欧拉通路-送货

时间:2020-08-28 11:48:31      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:continue   add   物流业务   小明   模板题   code   节点   iostream   size   

题目大意:

  为了增加公司收入,F公司新开设了物流业务。由于F公司在业界的良好口碑,物流业务一开通即受到了消费者的欢迎,物流业务马上遍及了城市的每条街道。然而,F公司现在只安排了小明一个人负责所有街道的服务。
  任务虽然繁重,但是小明有足够的信心,他拿到了城市的地图,准备研究最好的方案。城市中有n个交叉路口,m条街道连接在这些交叉路口之间,每条街道的首尾都正好连接着一个交叉路口。除开街道的首尾端点,街道不会在其他位置与其他街道相交。每个交叉路口都至少连接着一条街道,有的交叉路口可能只连接着一条或两条街道。
  小明希望设计一个方案,从编号为1的交叉路口出发,每次必须沿街道去往街道另一端的路口,再从新的路口出发去往下一个路口,直到所有的街道都经过了正好一次。

看到这个题就是一个一笔画的题,简单来说就是欧拉通路的模板题,欧拉通路可以用Hierholzer算法来做,大概思路就是递归去走一条路,然后删掉当前走过的边,直到走完所有的路。

本题要求字典序最小,那么就要每次扩展的时候选择最小结点号扩展就行了。

  无向图:

  1、存在欧拉回路的条件:原图连通,每个节点均为偶度节点。

  2、存在欧拉通路的条件:存在欧拉回路,或原图连通,有两个节点为奇度节点,其他节点均为偶度节点,而且出发顶点一定是奇数结点。

  有向图:

  1、存在欧拉回路的条件:基图(有向边变成无向边)连通,每个节点的入度等于出度。

  2、存在欧拉通路的条件:存在欧拉回路,或基图连通,有一个节点入度等于出度+1,有一个节点出度等于入度+1,其他节点入度等于出度,出发点的出度大于入度。

代码:

#include <iostream>
#include <algorithm>
#include <stack>
#include <cstring>
using namespace std;
//欧拉通路
const int N =1e5+10;
const int M =2e5+10;
int h[N],ne[M],to[M],idx=0;

void add(int a,int b){
    int last=-1;
    for(int i=h[a];~i;i=ne[i]){
        int v=to[i];
        if(b<v){
            if(last==-1){
                ne[idx]=h[a];
                to[idx]=b;
                h[a]=idx++;
            }
            else{
                ne[idx]=i;
                to[idx]=b;
                ne[last]=idx++;
            }
            return ;
        }
        last=i;
    }
    if(last==-1){
        ne[idx]=h[a];
        to[idx]=b;
        h[a]=idx++;
        return ;
    }
    ne[idx]=-1;
    to[idx]=b;
    ne[last]=idx++;
}

int d[N],vi[N],vii[M];
int cnt=0;


int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    memset(h,-1,sizeof h);
    for(int i=0;i<m;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
        d[a]++;
        d[b]++;
    }
    int odd=0;
    for(int i=1;i<=n;i++){
        if(d[i]&1)odd++;
    }
    stack<int> st1,st2;
    st1.push(1);
    while(st1.size()){
        int t=st1.top();
        int minj=h[t];
        
        if(minj==-1){
            st2.push(t);
            st1.pop();
        }
        else {
            if(vii[h[t]]){
                h[t]=ne[h[t]];
                continue;
            }
            int minid=to[h[t]];
            h[t]=ne[h[t]];
            vii[minj]=1;
            vii[minj^1]=1;
            st1.push(minid);
        }
    }
        
    if(st2.size()==m+1&&(odd==0||(odd==2&&d[1]%2))){
        while(st2.size()){
            printf("%d ",st2.top());
            st2.pop();
        }
        cout<<endl;
    }
    else puts("-1");
}

 

欧拉通路-送货

标签:continue   add   物流业务   小明   模板题   code   节点   iostream   size   

原文地址:https://www.cnblogs.com/kstranger/p/13547005.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!