• hdu 4687 带花树匹配


    其实吧,思路挺简单的,只不过昨天刚学,还有一些东西不太了解,然后就23333333.。。

    吃晚饭回来就A了,我是有多傻啊,这么题都A不掉,不能忍啊。。。

    我们可以先求出哪些边是可能存在于最大匹配中的,然后剩下的边就是绝对不可能在最大匹配中了

    求哪些边可能存在于最大匹配中,超简单,只需要强制将那条边上的两个点匹配(即删除),然后求最大匹配,如果是tot-1,那么这条边就可以存在于最大匹配中。

    ps:比赛的时候直接match[u]=v match[v]=u了,队友其实给我提供过正确的思路,只不过我太傻x,说多了都是泪。。。

    /* **********************************************
    Author      : wuyiqi
    Created Time: 2013-8-20 15:55:42
    File Name   : 1002.cpp
    *********************************************** */
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    //#define MAXE 300*300*2
    #define MAXN 300
    #define SET(a,b) memset(a,b,sizeof(a))
    deque<int> Q;
    //g[i][j]存放关系图:i,j是否有边,match[i]存放i所匹配的点
    bool g[MAXN][MAXN],inque[MAXN],inblossom[MAXN];
    int match[MAXN],pre[MAXN],base[MAXN];
     
    //找公共祖先
    int findancestor(int u,int v)
    {
        bool inpath[MAXN]={false};
        while(1)
        {
            u=base[u];
            inpath[u]=true;
            if(match[u]==-1)break;
            u=pre[match[u]];
        }
        while(1)
        {
            v=base[v];
            if(inpath[v])return v;
            v=pre[match[v]];
        }
    }
     
    //压缩花
    void reset(int u,int anc)
    {
        while(u!=anc)
        {
            int v=match[u];
            inblossom[base[u]]=1;
            inblossom[base[v]]=1;
            v=pre[v];
            if(base[v]!=anc)pre[v]=match[u];
            u=v;
        }
    }
     
    void contract(int u,int v,int n)
    {
        int anc=findancestor(u,v);
        SET(inblossom,0);
        reset(u,anc);reset(v,anc);
        if(base[u]!=anc)pre[u]=v;
        if(base[v]!=anc)pre[v]=u;
        for(int i=1;i<=n;i++)
            if(inblossom[base[i]])
            {
                base[i]=anc;
                if(!inque[i])
                {
                    Q.push_back(i);
                    inque[i]=1;
                }
            }
    }
     
    bool dfs(int S,int n)
    {
        for(int i=0;i<=n;i++)pre[i]=-1,inque[i]=0,base[i]=i;
        Q.clear();Q.push_back(S);inque[S]=1;
        while(!Q.empty())
        {
            int u=Q.front();Q.pop_front();
            for(int v=1;v<=n;v++)
            {
                if(g[u][v]&&base[v]!=base[u]&&match[u]!=v)
                {
                    if(v==S||(match[v]!=-1&&pre[match[v]]!=-1))contract(u,v,n);
                    else if(pre[v]==-1)
                    {
                        pre[v]=u;
                        if(match[v]!=-1)Q.push_back(match[v]),inque[match[v]]=1;
                        else
                        {
                            u=v;
                            while(u!=-1)
                            {
                                v=pre[u];
                                int w=match[v];
                                match[u]=v;
                                match[v]=u;
                                u=w;
                            }
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
     
    int solve(int n)
    {
        SET(match,-1);
        int ans=0;
        for(int i=1;i<=n;i++)
            if(match[i]==-1&&dfs(i,n))
                ans++;
        return ans;
    }
    bool vis[200];
    int a[200],b[200];
    bool mp[200][200];
    int main() {
        int n , m;
        while(scanf("%d%d",&n,&m) != EOF) {
           memset(g,false,sizeof(g));
           memset(vis,false,sizeof(vis));
           memset(mp,false,sizeof(mp));
           for(int i = 1; i <= m; i++) {
               scanf("%d%d",&a[i],&b[i]);
               g[a[i]][b[i]] = g[b[i]][a[i]] = true;
               mp[a[i]][b[i]] = mp[b[i]][a[i]] = true;
           }
           int ans = solve(n);
           for(int i = 1; i <= m; i++) {
               int x = a[i]  , y = b[i];
               memset(g,false,sizeof(g));
               for(int j = 1; j <= m; j++) if(i!=j){
                   if(a[j] == y && b[j] == x) continue;
                   int aa = a[j] , bb = b[j];
                   if(aa==x || aa==y || bb==x || bb==y) continue;
                   g[aa][bb] = g[bb][aa] = true;
               }
               int tmp = solve(n);
               if(tmp == ans - 1) {
                   vis[i] = true;
               }
           }
           vector<int> ret;
           for(int i = 1; i <= m; i++) if(!vis[i]) {
               ret.push_back(i);
           }
           printf("%d
    ",ret.size());
           if(ret.size()>0) {
               printf("%d",ret[0]);
               for(int i = 1; i < ret.size(); i++) {
                   printf(" %d",ret[i]);
               }
           }
           puts("");
        }
        return 0;
    }
    


  • 相关阅读:
    SpringCloudAlibaba
    wechat kill
    使用vscode调试 pomelo
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD 分析编辑页面添加搜索页面
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD添加视图(View)
    Terry的学习笔记ASP.NET MVC 4 简介
    正则表达式总结
    自己编写的 objectDataSource 配合 GridView 实现分页
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD 从控制器访问模型中的数据
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD添加控制器(Controller)
  • 原文地址:https://www.cnblogs.com/riskyer/p/3271301.html
Copyright © 2020-2023  润新知