hdu 5348 MZL's endless loop dfs
2015-08-05 20:19
429 查看
题意:给出一张图确定边的方向,使得每个点的abs(入度-出度) <= 1。
由于所有点总度数 = m*2,其中除去度数为偶数的点,那么剩下度数为奇数的点个数一定为偶数个,而度数为奇数的点,在一张图中只能为起点或者终点,偶数个这样的点说明了,这张图除去所有环之外(某个环里面的点度数一定是偶数),组成的森林中,一定能组成整数条只包含一个起点一个终点的路径,即假设x个度数为奇数的点,x为偶数,那么可以有x/2条路径,x/2个起点终点分别在这x/2条路径两端点。
所以对于每个点dfs,遇到环就消环,否则就直接从起点到终点深搜到底即可。
注意坑,考虑邻接表建双向边,边编号/2就是输入的点,一般edge_num都是从0开始- -而我m循环从1开始,被坑了好久
由于所有点总度数 = m*2,其中除去度数为偶数的点,那么剩下度数为奇数的点个数一定为偶数个,而度数为奇数的点,在一张图中只能为起点或者终点,偶数个这样的点说明了,这张图除去所有环之外(某个环里面的点度数一定是偶数),组成的森林中,一定能组成整数条只包含一个起点一个终点的路径,即假设x个度数为奇数的点,x为偶数,那么可以有x/2条路径,x/2个起点终点分别在这x/2条路径两端点。
所以对于每个点dfs,遇到环就消环,否则就直接从起点到终点深搜到底即可。
注意坑,考虑邻接表建双向边,边编号/2就是输入的点,一般edge_num都是从0开始- -而我m循环从1开始,被坑了好久
//#include <bits/stdc++.h> #include <map> #include <set> #include <queue> #include <stack> #include <cmath> #include <time.h> #include <vector> #include <cstdio> #include <string> #include <iomanip> ///cout << fixed << setprecision(13) << (double) x << endl; #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #define ls rt << 1 #define rs rt << 1 | 1 #define pi acos(-1.0) #define eps 1e-8 #define Mp(a, b) make_pair(a, b) #define asd puts("asdasdasdasdasdf"); typedef long long ll; //typedef __int64 LL; const int inf = 0x3f3f3f3f; const int N = 101000; struct node{ int v, nxt; }e[N*6]; int head ; int in , out ; int deg ; int n, m, cnt; int vis[N*6]; int ans[N*6]; void init() { memset( head, -1, sizeof( head ) ); memset( deg, 0, sizeof( deg ) ); memset( in, 0, sizeof( in ) ); memset( out, 0, sizeof( out ) ); memset( vis, 0, sizeof( vis ) ); cnt = 0; } void add( int u, int v ) { e[cnt].v = v; e[cnt].nxt = head[u]; head[u] = cnt++; e[cnt].v = u; e[cnt].nxt = head[v]; head[v] = cnt++; } void dfs( int u, int dir ) { for( int i = head[u]; ~i; i = e[i].nxt ) { if( vis[i] ) { head[u] = e[i].nxt; //邻接表删边 continue; } int v = e[i].v; if( dir == 1 ) { if( in[v] > out[v] && u != v ) //abs deg[v] >= 2 continue; out[u]++, in[v]++; } else { if( in[v] < out[v] && u != v ) continue; out[v]++, in[u]++; } vis[i] = vis[i^1] = 1; if( i % 2 ) //保证正向 ans[i/2] = dir^1; else ans[i/2] = dir; head[u] = e[i].nxt; dfs( v, dir ); break; } } int main() { int tot; scanf("%d", &tot); while( tot-- ) { scanf("%d%d", &n, &m); init(); for( int i = 1, u, v; i <= m; ++i ) { scanf("%d%d", &u, &v); deg[u]++, deg[v]++; add( u, v ); } for( int i = 1; i <= n; ++i ) { while( in[i]+out[i] < deg[i] ) { if( in[i] > out[i] ) dfs( i, 1 ); //zheng else dfs( i, 0 ); } } for( int i = 0; i < m; ++i ) printf("%d\n", ans[i]); } return 0; }
相关文章推荐
- Hadoop-HBASE 热添加新节点
- linux使用普通账户时,无法登录,提示“-bash: fork: retry: Resource temporarily unavailable”
- Linux时间子系统之一:clock source(时钟源)
- ubuntu下QQ下载和登陆(pidgin)
- 新手的linux之旅 一、准备工作
- Ubuntu 14.10 下Hadoop 错误集
- shell计算日期之间的天数
- linux命令2——进程相关
- Geoserver+Openlayers3加载瓦片地图
- Linux输入子系统(转)
- OpenGL坐标变换
- Openjudge6039 大师兄,师傅被妖怪抓走啦(模拟)
- tomcat Host及Context 配置
- centos hostname - 显示或设置主机名
- Openjudge6044 鸣人和佐助(bfs)
- CentOS用户切换
- 有关nginx Tornado tomcat apache<抄次网上>
- shell脚本学习笔记之正则表达式
- hadoop深入了解(三)
- UVa 714 Copying Books