HDU5348 MZL's endless loop (搜索)

来源:互联网 发布:淘宝子账号权重值500 编辑:程序博客网 时间:2024/06/08 19:08

题目链接: 传送门

题意:

给定一个无向图,让你给每个边加上方向使得每个点的|入度-出度|的绝对值小于等于1.

思路:

对于一个顶点我们每次寻找与他相连的一条链,如果当前个点的入度小于出度则我们将这条链的

方向设为使入度增加的放向。相反则设为使出度增加的放向。写的时候遍历过的边就不要再走了

因此需要删边。

Ps.比赛的时候YY感觉不可能有-1的情况但是没法证明,具体的证明请看:传送门


代码如下:

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;const int maxn = 1e5+10;int head[maxn],in[maxn],out[maxn],tot[maxn];bool vis[maxn*6];struct nod {    int to,next;} edge[6*maxn];int n,m,ip;int ans[maxn*6];void init(){    ip=0;    memset(head,-1,sizeof(head));    memset(vis,0,sizeof(vis));    memset(in,0,sizeof(in));    memset(out,0,sizeof(out));    memset(tot,0,sizeof(tot));}void add(int u,int v) {    edge[ip].to = v ;    edge[ip].next = head[u] ;    head[u] = ip++ ;}void dfs_in(int u) {    for(int i=head[u]; i!=-1; i=edge[i].next) {        if(vis[i]) {            head[u]=edge[i].next;            continue;        }        int v=edge[i].to;        if(u!=v && out[v]>in[v]) continue;        vis[i]=1,vis[i^1]=1; //标记,删边        head[u] = edge[i].next;        in[u]++,out[v]++;        if(i%2) ans[i/2] = 1;        else ans[i/2] = 0;        dfs_in(v);        return;    }}void dfs_out(int u) {    for(int i=head[u]; i!=-1; i=edge[i].next) {        if(vis[i]) {            head[u]=edge[i].next;            continue;        }        int v=edge[i].to;        if(u!=v && in[v]>out[v]) continue;        vis[i]=1,vis[i^1]=1; //标记,删边        head[u] = edge[i].next;        in[v]++,out[u]++;        if(i%2) ans[i/2] = 0;        else ans[i/2] = 1;        dfs_out(v);        return ;    }}int main() {    int t;    scanf("%d",&t);    while(t--) {        init();        scanf("%d%d",&n,&m);        for(int i=0; i<m; i++) {            int u,v;            scanf("%d%d",&u,&v);            add(u,v),add(v,u);            tot[u]++,tot[v]++;        }        memset(vis,0,sizeof(vis));        for(int i=1; i<=n; i++) {            while(out[i]+in[i]<tot[i]) {                if(out[i]>in[i]) dfs_in(i);                else dfs_out(i);            }        }        for(int i=0;i<m;i++)            printf("%d\n",ans[i]);    }    return 0;}


0 0
原创粉丝点击