zoukankan      html  css  js  c++  java
  • HDU 5639 Deletion 二分+网络流

    Deletion

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5639

    Description

    There is an undirected graph G with n vertices and m edges. Every time, you can select several edges and delete them. The edges selected must meet the following condition: let G′ be graph induced from these edges, then every connected component of G′ has at most one cycle. What is the minimum number of deletion needed in order to delete all the edges.

    Input

    There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

    The first line contains two integers n and m (1≤n≤2000,0≤m≤2000) -- the number of vertices and the number of edges.

    For the next m lines, each line contains two integers ui and vi, which means there is an undirected edge between ui and vi (1≤ui,vi≤n,ui≠vi).

    The sum of values of n in all test cases doesn't exceed 2⋅104. The sum of values of m in all test cases doesn't exceed 2⋅104.

    Output

    For each test case, output the minimum number of deletion needed.

    Sample Input

    3
    4 2
    1 2
    1 3
    4 5
    1 2
    1 3
    1 4
    2 3
    2 4
    4 4
    1 2
    2 3
    3 4
    4 1

    Sample Output

    1
    2
    1

    Hint

    题意

    给你一个图,你每次可以选择一些边删除

    要求你选择出来的边构成的图,每个连通块内最多构成一个环。

    问你最少删除几次

    题解:

    考虑每个连通块内只有一个环的这个图是啥。

    这是环套树,环套树有另外一个表示方法:

    对于每一个点,他的边是i,f[i],这样n条边所构成的图,一定是环套树。

    相当于每条边(u,v),可以作为u->v,也可以作为v->u

    所以最终的答案就是【所有点的出度的最大值】的最小值

    然后这个东西用网络流+二分就好了。

    瞎比跑一下就好了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=100000,MAXM=100000,inf=1e9;
    struct Edge
    {
        int v,c,f,nx;
        Edge() {}
        Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
    } E[MAXM];
    int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
    void init(int _n)
    {
        N=_n,sz=0; memset(G,-1,sizeof(G[0])*N);
    }
    void link(int u,int v,int c)
    {
        E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
        E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
    }
    bool bfs(int S,int T)
    {
        static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N);
        dis[S]=0; Q[0]=S;
        for (int h=0,t=1,u,v,it;h<t;++h)
        {
            for (u=Q[h],it=G[u];~it;it=E[it].nx)
            {
                if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                {
                    dis[v]=dis[u]+1; Q[t++]=v;
                }
            }
        }
        return dis[T]!=-1;
    }
    int dfs(int u,int T,int low)
    {
        if (u==T) return low;
        int ret=0,tmp,v;
        for (int &it=cur[u];~it&&ret<low;it=E[it].nx)
        {
            if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
            {
                if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                {
                    ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp;
                }
            }
        }
        if (!ret) dis[u]=-1; return ret;
    }
    int dinic(int S,int T)
    {
        int maxflow=0,tmp;
        while (bfs(S,T))
        {
            memcpy(cur,G,sizeof(G[0])*N);
            while (tmp=dfs(S,T,inf)) maxflow+=tmp;
        }
        return maxflow;
    }
    int n,m;
    pair<int,int> p[2050];
    bool check(int x)
    {
        int s=0,t=4002;
        init(4005);
        for(int i=1;i<=m;i++)
        {
            link(s,i+n,1);
            link(i+n,p[i].first,1);
            link(i+n,p[i].second,1);
        }
        for(int i=1;i<=n;i++)
            link(i,t,x);
        return dinic(s,t)==m;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
                scanf("%d%d",&p[i].first,&p[i].second);
            int l=0,r=m,ans=0;
            while(l<=r)
            {
                int mid=(l+r)/2;
                if(check(mid))r=mid-1,ans=mid;
                else l=mid+1;
            }
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    ArrayList用法
    Delegate比较全面的例子(原创)
    一个登陆页面,包含了初始化用户,输入检测,错误处理等
    C#线程 在某一时间内,只有N个线程在并发执行,其余都在队列中的实现
    ASP.Net防止刷新自动触发事件的解决方案
    存储过程编写经验和优化措施 (转)
    [转]数据库开发21条军规
    [转]Ajax简单客户登陆验证
    用SqlBulkCopy进行大批量数据迁移
    什么时候使用哪个数据绑定控件(asp.net)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5246222.html
Copyright © 2011-2022 走看看