hdu 5348 MZL's endless loop dfs

来源:互联网 发布:知乎怎么做微信销售 编辑:程序博客网 时间:2024/06/07 20:54

题意:给出一张图确定边的方向,使得每个点的abs(入度-出度) <= 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[N];int in[N], out[N];int deg[N];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;}


0 0