zoukankan      html  css  js  c++  java
  • 【百度之星】度度熊与排列【暴力+二分图匹配】

    题意:中文题,题意很好懂。要求每两个字符串重排以后编号要一样,可能有多种情况,就找字典序就小的。

    题解:一开始有点懵,然后发现要找的序列要满足所以字符串,不知所措。然后想到了那么多人过了,肯定暴力啊。然后就暴力二分图匹配,找到满足情况的i,j匹配起来。然后跑一个匈牙利,倒着跑(字典序最小)。然后就能得到结果啦。注意跑完以后还要看看匹配数量和link的值哦。

    #pragma comment(linker, "/STACK:102400000,102400000")
    #pragma GCC optimize(2)
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<cmath>
    #include<string>
    #include<map>
    #include<vector>
    #include<ctime>
    #include<stack>
    using namespace std;
    #define mm(a,b) memset(a,b,sizeof(a))
    typedef long long ll;
    map<long long,bool> M;
    const long long mod=1234577;
    const int maxn=1e6+10;
    ll gcd(ll x, ll y) {if (y == 0) return x; else return gcd(y, x % y); }
    const double eps=1e-8;
    int k;
    int g[600][600];
    int link[600];
    bool used[500];
    int n,m;
    bool dfs(int u)
    {
        int v;
        for(v=1;v<=m;v++)
            if(g[u][v]&&!used[v])
            {
                used[v]=true;
                if(link[v]==-1||dfs(link[v]))
                {
                    link[v]=u;
                    return true;
                }
            }
        return false;
    }
    
    int hungary()
    
    {
        int res=0;
        int u;
        memset(link,-1,sizeof(link));
        for(u=m;u>=1;u--)
        {
            memset(used,0,sizeof(used));
            if(dfs(u)) res++;
        }
        return res;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            mm(g,0);
            string N[25];
            scanf("%d %d",&n,&m);
            char s1[30][55],s2[30][55];
            for(int c=0;c<n;c++)
            {
                scanf("%s",s1[c]);
                scanf("%s",s2[c]);
            }
            for(int i=0;i<m;i++)
            {
                for(int j=0;j<m;j++)
                {
                    int flag=1;
                    for(int k=0;k<n;k++)
                    {
                        if(s1[k][i]!=s2[k][j])
                        {
                            flag=0;
                            break;
                        }
                    }
                    if(flag) g[j+1][i+1]=1;
                }
            }
            int ans=hungary();
            //printf("%d
    ",ans);
            int flag=1;
            for(int i=1;i<=m;i++)
            {
                if(link[i]==-1)
                {
                    flag=0;
                    break;
                }
            }
            if(!flag)
            {
                printf("-1
    ");
                continue;
            }
    
            for(int i=1;i<=m;i++)
            {
                printf("%d",link[i]);
                if(i!=m) printf(" ");
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    python数据类型
    集合(set)内置方法
    python第三天
    剑指offer-什么是1G/2G/3G/4G/5G
    经典交换实验-二层交换机实现pc隔离&vlan通信
    linux运维神器-htop&mtr
    三分钟速学linux-进程管理命令
    三分钟速学文件权限管理
    三分钟速学网卡管理配置-nmcli命令
    三分钟速学linux-centos/redhat常见包管理器
  • 原文地址:https://www.cnblogs.com/Tangent-1231/p/11375346.html
Copyright © 2011-2022 走看看