• HDU3718 Similarity KM


    原文链接http://www.cnblogs.com/zhouzhendong/p/8284763.html


    题目传送门 - HDU3718


    题意概括

      直接描述输入吧

      首先一个T(T<15),表示数据组数。

      每组数据,首先三个数:len,k,m,分别表示接下来要读入的字符串的长度、每一个字符串中出现的不同字母个种类数、询问的字符串数。(len<=10000)(k<=26)(m<30)

      然后一行一个标准串。(长度为len)

      然后m行,每行一个询问串。(长度为len)

      对于询问串,每一种字母可以对应一种字母,问在最优方案下,使得对应万之后满足询问串与标准串的对应位相同的位的个数除以len的值。

      完(kou)美(hu)


    题解

      我想骂人。

      容我说点难听的话。

      这题的样例数据简直就是垃圾。

      第46行的j++写成了i++居然过了样例然后实测无限TLE?

      

      言归正传。

      我们考虑每一个字母变成另一个字母得到的贡献,然后在这两个字母之间连一条边,边权为贡献。

      然后貌似就是裸的KM了。

      OK水题。


    代码

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int INF=1e9+7;
    const int N=30,L=10005;
    int T,len,n,m,g[N][N];
    char cor[L],now[L];
    int ex[N],ey[N],minadd[N],match[N];
    bool visx[N],visy[N];
    bool Match(int x){
    	visx[x]=1;
    	for (int i=1;i<=n;i++)
    		if (!visy[i]){
    			int add=ex[x]+ey[i]-g[x][i];
    			if (!add){
    				visy[i]=1;
    				if (!match[i]||Match(match[i])){
    					match[i]=x;
    					return 1;
    				}
    			}
    			else
    				minadd[i]=min(minadd[i],add);
    		}
    	return 0;
    }
    int KM(){
    	memset(match,0,sizeof match);
    	memset(ex,0,sizeof ex);
    	memset(ey,0,sizeof ey);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			ex[i]=max(ex[i],g[i][j]);
    	for (int i=1;i<=n;i++){
    		for (int j=1;j<=n;j++)
    			minadd[j]=INF;
    		while (1){
    			memset(visx,0,sizeof visx);
    			memset(visy,0,sizeof visy);
    			if (Match(i))
    				break;
    			int d=INF;
    			for (int j=1;j<=n;j++)
    				if (!visy[j])
    					d=min(d,minadd[j]);
    			for (int j=1;j<=n;j++){
    				if (visx[j])
    					ex[j]-=d;
    				if (visy[j])
    					ey[j]+=d;
    				else
    					minadd[j]-=d;
    			}
    		}
    	}
    	int ans=0;
    	for (int i=1;i<=n;i++)
    		ans+=g[match[i]][i];
    	return ans;
    }
    void readstr(char s[]){
    	char ch[5];
    	for (int i=1;i<=len;i++){
    		scanf("%s",ch);
    		s[i]=ch[0];
    	}
    }
    int main(){
    	scanf("%d",&T);
    	while (T--){
    		scanf("%d%d%d",&len,&n,&m);
    		n=26;
    		readstr(cor);
    		while (m--){
    			readstr(now);
    			memset(g,0,sizeof g);
    			for (int i=1;i<=len;i++)
    				g[now[i]-'A'+1][cor[i]-'A'+1]++;
    			printf("%.4lf
    ",1.0*KM()/len);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    G级别的文本文件分割器FileSpliter
    zabbix5.2.6性能优化001、数据库的优化
    Zabbix 6.0 使用Elasticsearch作为 后端数据库
    zabbix 5.2.6 升级到 6.0.1
    Linux 系统常用命令
    zabbix获取历史告警问题
    Kubernetes1.20.1 下 部署Prometheus+nodeexporter+Grafana+AlertManager 监控系统
    第一天
    zabbix 5.2.6不定时重启, 日志报错 failed to open log file: [24] Too many open files
    CentOS 7.6 部署 elasticsearch kibana 7.9.1
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU3718.html
Copyright © 2020-2023  润新知