[hdu5348]图上找环,删环
http://acm.hdu.edu.cn/showproblem.php?pid=5348
题意:给一个无向图,现在要将其变成有向图,使得每一个顶点的|出度-入度|<=1
思路:分为两步,(1)从图上找环,将环上边的方向设为一致,这样直到图中不存在环,最后剩下一个森林(2)对每一棵树的边进行编号,方法是从根节点向下,对每个点,将其与第一个儿子之间的边设置为与父亲之间的边“互补”的方向,而与儿子之间边的方向则交替分配,显然无论儿子多少个,这个点的出度与入度之差不会超过1。这样两步完成后,所有边都有了方向,所以对任意图都是有解的。自环和重边不需要特殊对待。
无向图上找环: 由于是无向图上任意找环,所以存在这样的性质:如果此时此刻从当前边出发找不到环,那么以后再访问这条边时,也同样找不到环,也就是说如果这条边在某个环上,那么现在就可以找到,所以对同一条边访问一次即可。注意代码里面遍历边时,用一个数组表示这个点边集合的入口,一边遍历一边改变入口,这样下次到这个点时,就跳过了以前访问过的从这个点出发的边。
至于删环,用数组标记下即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#include <map> #include <set> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define X first #define Y second #define pb push_back #define mp make_pair #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) typedef long long ll; typedef pair< int , int > pii; typedef unsigned long long ull; #ifndef ONLINE_JUDGE void RI(vector< int >&a, int n){a.resize(n); for ( int i=0;i<n;i++) scanf ( "%d" ,&a[i]);} void RI(){} void RI( int &X){ scanf ( "%d" ,&X);} template < typename ...R> void RI( int &f,R&...r){RI(f);RI(r...);} void RI( int *p, int *q){ int d=p<q?1:-1; while (p!=q){ scanf ( "%d" ,p);p+=d;}} void print(){cout<<endl;} template < typename T> void print( const T t){cout<<t<<endl;} template < typename F, typename ...R> void print( const F f, const R...r){cout<<f<< ", " ;print(r...);} template < typename T> void print(T*p, T*q){ int d=p<q?1:-1; while (p!=q){cout<<*p<< ", " ;p+=d;}cout<<endl;} #endif template < typename T> bool umax(T&a, const T&b){ return b<=a? false :(a=b, true );} template < typename T> bool umin(T&a, const T&b){ return b>=a? false :(a=b, true );} template < typename T> void V2A(T a[], const vector<T>&b){ for ( int i=0;i<b.size();i++)a[i]=b[i];} template < typename T> void A2V(vector<T>&a, const T b[]){ for ( int i=0;i<a.size();i++)a[i]=b[i];} const double PI = acos (-1.0); const int INF = 1e9 + 7; /* -------------------------------------------------------------------------------- */ const int maxn = 1e5 + 7; pii E[maxn * 6]; int SZ; int Next[maxn * 6]; int last[maxn]; int n; bool ans[maxn * 6], markE[maxn * 6], dif[maxn], flag[maxn], vis[maxn]; int mark[maxn]; void add( int u, int v) { E[SZ ++] = mp(u, v); E[SZ ++] = mp(v, u); Next[SZ - 2] = last[u]; last[u] = SZ - 2; Next[SZ - 1] = last[v]; last[v] = SZ - 1; } stack< int > S; bool now = 0; void DeleteRing( int u) { if (flag[u]) { while (S.top() != u) { flag[S.top()] = false ; S.pop(); } now = true ; return ; } S.push(u); flag[u] = true ; for ( int &i = mark[u]; ~i; i = Next[i]) { int id = i; pii &e = E[id]; if (!vis[e.Y] && !markE[id]) { markE[id] = true ; markE[id ^ 1] = true ; ans[id] = true ; DeleteRing(e.Y); if (S.top() != u) return ; if (now) { now = false ; continue ; } markE[id] = false ; markE[id ^ 1] = false ; ans[id] = false ; } } S.pop(); flag[u] = false ; vis[u] = true ; } void dfs( int u) { vis[u] = true ; for ( int i = last[u]; ~i; i = Next[i]) { int id = i; pii &e = E[id]; if (!vis[e.Y] && !markE[id]) { markE[id] = true ; markE[id ^ 1] = true ; ans[id ^ dif[u]] = true ; dif[e.Y] = dif[u]; dif[u] ^= 1; dfs(e.Y); } } } int main() { #ifndef ONLINE_JUDGE freopen ( "in.txt" , "r" , stdin); //freopen("out.txt", "w", stdout); #endif // ONLINE_JUDGE int T, u, v, m; cin >> T; while (T --) { cin >> n >> m; SZ = 0; fillchar(last, -1); fillchar(Next, -1); fillchar(ans, 0); fillchar(vis, 0); fillchar(markE, 0); for ( int i = 0; i < m; i ++) { scanf ( "%d%d" , &u, &v); add(u, v); } for ( int i = 1; i <= n; i ++) mark[i] = last[i]; for ( int i = 1; i <= n; i ++) { if (!vis[i]) DeleteRing(i); } fillchar(vis, 0); fillchar(dif, 0); for ( int i = 1; i <= n; i ++) { if (!vis[i]) dfs(i); } for ( int i = 0; i < SZ; i += 2) { printf ( "%d\n" , ans[i]); } } return 0; } |
[hdu5348]图上找环,删环的更多相关文章
- HDU 2147 kiki's game(博弈图上找规律)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2147 题目大意:给你一个n*m的棋盘,初始位置为(1,m),两人轮流操作,每次只能向下,左,左下这三个 ...
- HDU 1253 三维数组的图上找最短路
题目大意: 从三维空间的(0,0,0)出发到(a-1,b-1,c-1),每移动一个都要时间加一,计算最短时间 根据六个方向,开个bfs,像spfa那样计算最短路径就行了,但是要1200多ms,也不知道 ...
- 【学习笔记】有向无环图上的DP
手动博客搬家: 本文发表于20180716 10:49:04, 原地址https://blog.csdn.net/suncongbo/article/details/81061378 首先,感谢以下几 ...
- HDU 3249 Test for job (有向无环图上的最长路,DP)
解题思路: 求有向无环图上的最长路.简单的动态规划 #include <iostream> #include <cstring> #include <cstdlib ...
- qbxt的题:找一个三元环
有向图中找一个三元环 题意: 考虑 N 个人玩一个游戏, 任意两个人之间进行一场游戏 (共 N*(N-1)/2 场),且每场一定能分出胜负.现在,你需要在其中找到三个人构成的这样的局面:A战胜B,B战 ...
- SPFA找最大比例环
SPFA找最大比例环 ans=Σ点权/Σ边权 所以 可以变式为 Σ边权*ans-Σ点权=0 要找出最大的ans 可以二分 边权值变为 目的地点权-ans*边权 检查是否有负环 有则可以更优 #incl ...
- 动态规划 洛谷P4017 最大食物链计数——图上动态规划 拓扑排序
洛谷P4017 最大食物链计数 这是洛谷一题普及/提高-的题目,也是我第一次做的一题 图上动态规划/拓扑排序 ,我认为这题是很好的学习拓扑排序的题目. 在这题中,我学到了几个名词,入度,出度,及没有环 ...
- thinkphp5多图上传 js部分
在项目中常会用到多图上上传,那就需要多图上传后需要预览,并且能删掉传错(不想传)的图,然而 测试了半天 并不知道jq怎么写,parent()parents()用了半天无果,罢了,还是用原生js来写.这 ...
- 2019-ACM-ICPC-南京区网络赛-D. Robots-DAG图上概率动态规划
2019-ACM-ICPC-南京区网络赛-D. Robots-DAG图上概率动态规划 [Problem Description] 有向无环图中,有个机器人从\(1\)号节点出发,每天等概率的走到下 ...
随机推荐
- NK16
C 小石的海岛之旅 链接:https://ac.nowcoder.com/acm/contest/949/C来源:牛客网 暑假到了,小石和小雨到海岛上玩. 从水平方向看海岛可以看成 nnn个小块,每一 ...
- Flutter Weekly Issue 52
教程 一个易迁移.兼容性高的 Flutter 富文本方案 复杂业务如何保证Flutter的高性能高流畅度? 插件 flutter_color_models A wrapper for the Dart ...
- python3+selenium3自动化1——元素定位
1.selenium的webdriver提供了八种基本的元素定位方法 打开浏览器 driver = webdriver.Chrome() driver.get('https://www.baidu.c ...
- synchronized 代码块怎么用
加不加 synchronized 有什么区别? synchronized 作为悲观锁,锁住了什么? 之前 2 篇文章我们已经知道 synchronized 的使用方法以及锁的内容(实例对象和Class ...
- 微信小程序弹出层动画特效
.rules_modal_cont{ height:800rpx; width:200rpx; -webkit-animation: showZeroAlert .3s; animation: sho ...
- 替换字符串sql
update [表名] set 字段名 = replace(与前面一样的字段名,'原本内容','想要替换成什么') UPDATE `zjl_III_hei_zlj_20151111`.`ctrl_ne ...
- java零基础自学网站分享
俗话说工欲善其事,必先利其器,今天给大家分享一个java自学网站:how2j,这是一个有十年淘宝工作经验大牛的制作的网站,距离现在已经有三四年了,这个网站包含的知识非常的多,从基础的环境变量配置一直到 ...
- 基于java的OpenCV安装和配置
目录 OpenCV简介 OpenCV下载安装 eclipse里引用jar包和配置 OpenCV简介 OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Window ...
- (数据科学学习手札82)基于geopandas的空间数据分析——geoplot篇(上)
本文示例代码和数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在前面的基于geopandas的空间数据分 ...
- socket编程-多个客户端向服务器发送人脸照片,服务器返回识别结果(服务器使用多线程)...
recognition.py import numpy as np import face_recognition import os class recognition: def __init__( ...