您的位置:首页 > 运维架构

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开始,被坑了好久

//#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: