题解——星际旅行(欧拉路)

一道很巧妙的欧拉路问题,细节也要注意


题面

Description
题面已隐藏

Input
一个图

Output
一个整数表示最低花费

in.1
5 4
1 2
1 3
1 4
1 5

out.1
6

数据范围与约定

对于100%数据,n,m<=1e5 ,其他隐藏

思路

主要思路
由题意得,我们只需要将每条边翻倍,再在所有边中选择两条不同的边,将其删除,如果满足欧拉路或者欧拉回路,就可以得到一种本质不同的方案。

主要分为两部分:

1.判断联通,如果不连通,方案数肯定为0
2.分类统计处理贡献

处理:

1.判断联通可以建图跑一次dfs个每条边打标记,也可以不建图用并查集,两种方法都是 O(n)

2.好了关键来了。

前提:边翻倍后,所有点的度数变为偶数。
Cndition1:删除两个自环。由于自环对一个点的影响都是偶数,任意选择两个自环删去,所以始终满足欧拉回路。ans += C( 2 , m )
Cndition2:删除一个自环+一条边。由于自环对一个点的影响都是偶数,忽略,而一条边使两个点的度数变为奇数,所以始终满足欧拉路。ans += 路径条数 X 自环数
Cndition3:删除两条边,无法满足欧拉回路条件,要保证满足欧拉路条件,选择的两条边一定有一个共同点。所以对每个初始度数(不翻倍)>= 2 的点,统计贡献 。 ans += ∑ C( 2 , du[ i ] )。

细节:
1.如使用dfs判联通,注意累计次数退出环,否则爆栈。
2.由于不能删翻倍后的同一条重边,上述做法中删除后图始终保持联通。

DFS版本(from ssw02 )

#include<bits/stdc++.h>
using namespace std ;
#define ll long long
const int MAXN = 100005 ;
inline int read(){int s=0 ;char g=getchar(); while(g>'9'||g<'0')g=getchar() ; while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ;
}
ll ans = 0LL , sum = 0LL , cnt = 0LL , du[ MAXN ] ;
int  N , M , head[ MAXN ] , to[ MAXN*2 ] , nex[ MAXN*2 ] , tot = 1 , vis[ MAXN ];//边 自环
bool  used[ MAXN*2 ] , key ;
void  add( int x , int y ){to[ ++tot ] = y , nex[ tot ] = head[ x ] , head[ x ] = tot ;
}
void  check(){for( int i = 2 ; i <= tot ; ++i )if( !used[ i ] ){key = true ; break ;}
}
void  dfs( int u , int fa ){vis[ u ]++ ;if( vis[ u ] > 10 )return ;//平时开大点,这里数据水for( int i = head[ u ] ; i ; i = nex[ i ] ){used[ i ] = true ;if( to[i] == fa || to[ i ] == u )continue ;dfs( to[i] , u ) ;}
}
int main(){N = read() , M = read() ; int  m1 , m2 ;for( int i = 1 ; i <= M ; ++i ){m1 = read() , m2 = read() ; add( m1 , m2 ) , add( m2 , m1 ) ;if( m1 != m2 )sum++ , du[ m1 ]++ , du[ m2 ]++ ;else cnt++ ;}for( int i = 1 ; i <= N ; ++i )if( head[ i ] ){dfs( i , i )  ; break ;}check();if( key ){ printf("0");return 0 ;}if( cnt >= 2 )ans = (ll)cnt*(ll)(cnt-1LL)/2LL ;if( cnt >= 1 && sum >= 1 )ans += (ll)sum*cnt ;if( sum >= 2 )for( int i = 1 ; i <= N ; ++i )ans += ( (ll)du[i]*(du[i]-1LL) )/2LL ;cout<<ans ;
} 

并查集版本(std)

#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 1000010
int fa[maxn],siz[maxn];
int findfa(int p)
{if(fa[p]!=p) fa[p]=findfa(fa[p]);return fa[p];
}
void uni(int p,int q)
{p=findfa(p),q=findfa(q);if(p!=q){fa[p]=q;siz[q]+=siz[p];}
}
int n,m,l[maxn],r[maxn];
int du[maxn],sig;
bool v[maxn];
int main()
{scanf("%d%d",&n,&m);for(int i=1; i<=n; i++) fa[i]=i,siz[i]=1;for(int i=1; i<=m; i++){scanf("%d%d",&l[i],&r[i]);uni(l[i],r[i]);if(l[i]!=r[i]){du[l[i]]++;du[r[i]]++;}else sig++;}int lst=findfa(l[1]);for(int i=2; i<=m; i++)if(findfa(l[i])!=lst) {lst=-1; break;}if(lst==-1) cout<<0<<endl;else{long long ans=0;ans+=1ll*sig*(sig-1)/2;ans+=1ll*sig*(m-sig);for(int i=1; i<=n; i++)ans+=1ll*du[i]*(du[i]-1)/2;cout<<ans<<endl;}return 0;
}

如有不足,请大佬指出

转载于:https://www.cnblogs.com/ssw02/p/11409002.html

题解——星际旅行(欧拉路)相关推荐

  1. 小A与欧拉路(牛客-树的直径)

    题解: 欧拉路:从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边只通过恰好一次 问你走完这树上所有的点最短路径是什么. 因为树是没有环的,所以你走到叶子结点的时候需要往回走,也就是再走一 ...

  2. 【cf789D】Weird journey(欧拉路、计数)

    cf788B/789D. Weird journey 题意 n个点m条边无重边有自环无向图,问有多少种路径可以经过m-2条边两次,其它两条边1次.边集不同的路径就是不同的. 题解 将所有非自环的边变成 ...

  3. 【Luogu1341】无序字母对(并查集联通,欧拉路模板)

    problem 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒). 请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输出字典序最小的方案(n的规模 ...

  4. HDU1116 Play on Words——欧拉路(有向图+并查集)

    点这里 题意: T组输入,每组输入有n个单词,要求将所有单词两两首尾相连,要求是前一个单词的最后一个字母和后一个单词的最后一个字母必须相同.如果能将所有单词连成一串,输出Ordering is pos ...

  5. 小A与欧拉路 (树加边求最小权值欧拉路+树的直径)

    链接:https://ac.nowcoder.com/acm/contest/369/C 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言2621 ...

  6. 海亮Day2:差分约束、拓扑排序、欧拉路

    海亮第二天,想着说预习一下的,可是昨天10h+都没有把那六道题打完,就打了四道,上午就讲完课了,还是延续昨天的博客,今天接着总结.. 欧拉路 开头就是特别经典的七桥问题,讲欧拉路一定会讲到的问题,也就 ...

  7. 图论--欧拉路,欧拉回路(小结)

    在题目中在慢慢细说概念 1.HDU - 3018 Ant Trip 题目大意:又N个村庄,M条道路.问须要走几次才干将全部的路遍历 解题思路:这题问的是有关欧拉路的判定 欧拉路就是每条边仅仅能走一次, ...

  8. 图论-欧拉路(UVA10054)(HDU1116)

    首先说一下定义: 欧拉路:从图中某点出发可以遍历全图,图中的每条边通过且只能通过一次. 欧拉回路:具有欧拉路性质且起点位置与终点位置相同. 主要问题就是一个图中是否存在欧拉路,和打印欧拉路路径. 先说 ...

  9. 模板 - 欧拉路、欧拉回路(一笔画问题)

    整理的算法模板合集: ACM模板 目录 非递归版 普通递归版 HierholzersHierholzersHierholzers算法(输出字典序最小的答案) FleuryFleuryFleury算法 ...

最新文章

  1. android ijkplayer使用_Ijkplayer、ExoPlayer、VLC播放器综合比较
  2. source insight使用
  3. active mq topic消费后删除_《我想进大厂》之MQ夺命连环11问
  4. Netty工作笔记0029---NIO 网络编程应用--群聊系统4--客户端编写2
  5. 科创人·优艾智合创始人张朝辉:死磕细分行业Know-How,中国制造将引领全球移动机器人市场
  6. 密码系列-Base32
  7. 使用typedef定义数据类型
  8. 这是 qq整人代码 VB
  9. Rhino7.4软件安装教程
  10. “2019/10/17创新创业工坊第六期第二课”心得体会
  11. windows10共享移动热点(或说 电脑开WIFI),让手机连接共享的移动热点WIFI
  12. QT 自学内容 day03 listWidget ,treeWidget,tableWidget ,stackedWidget,模态,和非模态 多种 对话框的的使用
  13. HRBUST1313-火影忍者之~静音
  14. 通过浏览器中的F12中来查看接口的入参、出参和网页响应时间(新手教程)
  15. 数据分析师 知识体系 业务篇
  16. ubuntu系统搭建steam饥荒联机服务器
  17. html5手机号输入框,input输入框限制(座机,手机号码)
  18. iOS 企业包无法安装
  19. (PDC2008)Anders Hejlsberg: The Future of C#
  20. matlab 邻近度 离群点_Matlab 学习记录帖 —— 多项式、插值和数据拟合

热门文章

  1. 小程序如何关联企业微信
  2. 七步教你从0到1创建客户服务团队
  3. 2022年数据库审计产品排行榜-必看!
  4. VF200(VF101-N)产品重庆平台操作指导书_v2.1.24_20201020
  5. 西门子携手太古可口可乐打造饮料行业数字化标杆
  6. 挥一挥衣袖,开始一段新的旅程
  7. 【创业邦·年度创业人物】刘强东:十年战争与千亿美金帝国梦
  8. ZBrush中Magnify膨胀笔刷介绍
  9. Leetcode之Russian Doll Envelopes
  10. 阿里云学生服务器专注于学生搭建个人博客