HDU5348

来源:互联网 发布:办理网络400电话 编辑:程序博客网 时间:2024/05/19 00:16
题意:给一个无向图,让你指定边的方向,比如a→b为1,a←b为0,在给所有边指定方向后,对无向图上的每个顶点,如果满足|出度-入度|<2,那么输出一种方案。

思路:从结论入手,|出度-入度|<2,那么只能为0或1,对于0的情况,应该是出度等于入度,所以每个顶点都有偶数个度,既偶数条边,如果为1的话,一定是奇数条边,所以对于第二种情况,因为奇数边的点要么是起点,要么是终点(搜索),我们先对奇数边的点dfs,然后更改奇数边点的度数(删边),使之全部为偶数边,用line来存储相关联的两条边,index存储边的下标,value存储边的方向,total存放点的总度数。


#include <iostream>#include <stdio.h>#include <cstring>#include <vector>#define MAX 500050using namespace std;vector<int> line[MAX],index[MAX],value[MAX];int total[MAX],flag[MAX],ans[MAX];int t,n,m;void init (){    for ( int i = 0 ; i <= n ; i++ )    {        line[i].clear();        index[i].clear();        value[i].clear();    }    memset ( total , 0 , sizeof ( total ));    memset ( flag , 0 , sizeof ( flag ));}void dfs ( int u ){    int len = line[u].size()-1;    for ( int i = len ; i >= 0; i-- )    {        int v = line[u][i];        int x = index[u][i];        int c = value[u][i];        line[u].pop_back();        if ( flag[x] ) continue;        total[u]--;        total[v]--;        ans[x] = c;        flag[x] = 1;        dfs ( v );        break;    }}void solve(){    for ( int u=1 ; u<=n;u++ )        if (total[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]);}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 );            line[u].push_back ( v );            index[u].push_back ( i );            value[u].push_back ( 1 );            line[v].push_back ( u );            index[v].push_back ( i );            value[v].push_back ( 0 );            total[u]++;            total[v]++;        }        solve();    }}




0 0
原创粉丝点击