zoukankan      html  css  js  c++  java
  • hdu4685

    题解:

    二分图匹配

    对于每一个单身狗

    见一个虚拟的人

    然后就可以做了

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2000;
    const int M=1000000+3000;
    struct EDGE{int v,next;}edge[M];
    int first[N],low[N],dfn[N],sta[M],belong[N];
    int ans[N],match[N],flag[N];
    bool instack[N],vis[N];
    int n,m,g,cnt,top,scc,maxn;
    int Scan()  
    {
        int res=0,ch,flag=0;
        if ((ch=getchar())=='-')
            flag=1;
        else if (ch>='0'&&ch<='9')
            res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')
            res=res*10+ch-'0';
        return flag?-res:res;
    }
    void Out(int a)
    {
        if (a>9)
            Out(a/10);
        putchar(a%10+'0');
    }
    void AddEdge(int u,int v)
    {
        edge[g].v=v;
        edge[g].next=first[u];
        first[u]=g++;
    }
    int min(int a,int b)
    {
        return a<b?a:b;
    }
    int max(int a,int b)
    {
        return a>b?a:b;
    }
    void init()
    {
        g=cnt=top=scc=0;
        memset(first,-1,sizeof(first));
        memset(dfn,0,sizeof(dfn));
        memset(instack,0,sizeof(instack));
        memset(flag,0,sizeof(flag));
        n=Scan();
        m=Scan();
        maxn=max(n,m);   
    }
    bool dfs(int u)
    {
        int i,v;
        for (i=first[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].v;
            if (!vis[v])
            {
                vis[v]=1;
                if (match[v]==0||dfs(match[v]))
                {
                    match[v]=u;
                    flag[u]=v;
                    return 1;
                }
            }
        }
        return 0;
    }
    void xiong()   
    {
        int i;
        memset(match,0,sizeof(match));
        for (i=1;i<=maxn;i++)
        {
            memset(vis,0,sizeof(vis));
            dfs(i);
        }
    }
    void Tarjan(int u)
    {
        low[u]=dfn[u]=++cnt;
        sta[++top]=u;
        instack[u]=1;
        for (int i=first[u];i!=-1;i=edge[i].next)
         {
            int v=edge[i].v;
            if (!dfn[v])
             {
                Tarjan(v);
                low[u]=min(low[u],low[v]);
             }
            else if (instack[v])low[u]=min(low[u],dfn[v]);
         }
        if (low[u]==dfn[u])
        {
            scc++;
            while (1)
             {
                int v=sta[top--];
                instack[v]=0;
                belong[v]=scc;
                if (u==v)
                    break;
             }
         }
    }
    void build()
    {
        int i,k,v,j;
        for (i=1;i<=n;i++)
        {
            k=Scan();
            while(k--)
            {
                v=Scan();
                AddEdge(i,v+maxn);   
            }
        }
        xiong();  
        int all=2*maxn;
        for (i=1;i<=maxn;i++)   
        {
            if (!flag[i])
            {
                all++;
                for (j=1;j<=maxn;j++) 
                    AddEdge(j,all);
                match[all]=i;
                flag[i]=all;
            }
        }
    
        for (i=maxn+1;i<=2*maxn;i++)  
        {
            if (!match[i])
            {
                all++;
                for (j=maxn+1;j<=2*maxn;j++) 
                    AddEdge(all,j);
                flag[all]=i;
                match[i]=all;
            }
        }
        for (i=1;i<=all;i++)  
         if (flag[i])AddEdge(flag[i],i);
    }
    void solve()
    {
        int i,u,v;
        for (i=1;i<=maxn;i++) 
         if (!dfn[i])Tarjan(i);
        for (u=1;u<=n;u++)
        {
            int count=0;
            for (i=first[u];i!=-1;i=edge[i].next)
            {
                v=edge[i].v;
                if (belong[u]==belong[v])
                {
                    if (v-maxn>m)
                        continue;
                    ans[count++]=v-maxn;
                }
            }
            sort(ans,ans+count);
            Out(count);
            for (i=0;i<count;i++)
             {
                putchar(' ');
                Out(ans[i]);
             } 
            putchar('
    ');
         }
    }
    int main()
    {
        int t=Scan();
        for (int cas=1;cas<=t;cas++)
         {
            init();
            build();
            printf("Case #%d:
    ",cas);
            solve();
         }
        return 0;
    }
  • 相关阅读:
    为什么不要在Spring的配置里,配置上XSD的版本号
    使用GIT管理UE4代码
    C++ 编程错误记录
    Maven 命令及其他备忘
    Windows API 之 CreateToolhelp32Snapshot
    Windows API 之 ReadProcessMemory
    Windows API 之 OpenProcessToken、GetTokenInformation
    利用未文档化API:RtlAdjustPrivilege 提权实现自动关机
    WindowsAPI 之 CreatePipe、CreateProcess
    错误: error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. 的处理方法
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8270414.html
Copyright © 2011-2022 走看看