hdu 5348 MZL's endless loop(dfs+图论)

来源:互联网 发布:简述网络贷款的危害 编辑:程序博客网 时间:2024/05/22 11:39

题目连接:

hdu 5348


题目大意:

给出一个无向图,给边确定方向,让每个顶点的|入度-出度|<=1,给出一个可行的方案。


题目分析:

首先对于每个度数为奇数的点,一定是一条路径的起点或者终点,所以我们从这个点开始搜索,会导致两个奇数点变为偶数点,如果一个连通图中均是偶数点或者只有一个奇数点,那么走一遍欧拉路一定能够遍历所有的边。所以我们先把奇数点统统变成偶数点,然后通过一遍dfs就能将每个连通图的每条边都确定方向。因为如果连通图中如果所有点都是偶数点,每个有一个入度就就会出现一个出度。所以每个图一定有解。


AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#define MAX 100007using namespace std;vector<int> e[MAX];vector<int> id[MAX];vector<int> col[MAX];int d[MAX];int mark[MAX<<2];int ans[MAX<<2];int t,n,m;/*struct edge{    int v,next,id,dir;}e[MAX<<3];int head[MAX];int cc;*//*inline void add ( int u , int v , int i , int d ){    e[cc].v = v;    e[cc].id = i;    e[cc].dir = d;    e[cc].next = head[u];    head[u] = cc++;}*//*void init (){    memset ( mark , 0 , sizeof ( mark ));    memset ( d , 0 , sizeof ( d ));    memset ( head , -1 , sizeof ( head ));    cc = 0;}*/inline void add ( int u , int v , int i ){    e[u].push_back ( v );    id[u].push_back ( i );    col[u].push_back ( 1 );    e[v].push_back ( u );    id[v].push_back ( i );    col[v].push_back ( 0 );}void init (){    for ( int i = 0 ; i <= n ; i++ )    {        e[i].clear();        id[i].clear();        col[i].clear();    }    memset ( d , 0 , sizeof ( d ));    memset ( mark , 0 , sizeof ( mark ));}void dfs ( int u ){    int len = e[u].size()-1;    for ( int i = len ; i >= 0; i-- )    {        int v = e[u][i];        int x = id[u][i];        int c = col[u][i];        e[u].pop_back();        if ( mark[x] ) continue;        d[u]--;        d[v]--;        ans[x] = c;        mark[x] = 1;        dfs ( v );        break;    }}/*void dfs ( int u ){    for ( int& i = head[u] ;  ~i ; i = e[i].next )    {        int v = e[i].v;        int x = e[i].id;        int c = e[i].dir;        if ( mark[x] ) continue;        d[u]--;        d[v]--;        ans[x] = c;        mark[x] = 1;        dfs ( v );        break;    }}*/int main ( ){    scanf ( "%d" , &t );    while ( t-- )    {        scanf ("%d%d" , &n , &m );        init ();        for ( int i = 0 ; i < m ; i++ )        {            int u,v;            scanf ( "%d%d" , &u , &v );            //add ( u , v , i , 1);            //add ( v , u , i , 0);            add ( u ,v ,i );            d[u]++,d[v]++;        }        for ( int u = 1 ; u <= n ; u++ )            if ( d[u]&1 )                dfs ( u );        for ( int u = 1 ; u <= n ; u++ )            dfs ( u );        for ( int i = 0 ; i < m ; i++ )            printf ( "%d\n" , ans[i] );    }}
0 0
原创粉丝点击