HDU3718/ZOJ3425 Similarity(The 2010 ACM-ICPC Asia Chengdu Regional Contest,加权二分图的最优匹配)
来源:互联网 发布:mysql 修改字段属性 编辑:程序博客网 时间:2024/05/22 08:49
只要能看出来是二分图的最优匹配,然后建图,套模板,应该就能过了,几乎是裸模板题,听 亚伟 说去年现场赛的时候小伟他们1Y过掉这个题,然后就尝试了下,的确不是很难,这又给了我们弱小心灵一点点希望和安慰……
我用的是 KM算法 ,调整顶标值加上一直 dfs 找增广路(就是二分图最大匹配的匈牙利算法),具体解释参见:
http://hi.baidu.com/wwbmmm/blog/item/7f356cfa92d23962034f56e5.html
PS:不要光看博文,下面有个牛牛的评论,相当给力!!!
我的代码:
#include<cstdio>#include<iostream>#include<cstring>#include<climits>#define min(a,b) a<b?a:b#define max(a,b) a>b?a:bconst int N = 30;struct point{char name;int id;};point pa[N],pb[N];int map[N][N],len,g,stu;void addpoint_a(char x,int &k1){//构造二分图的x点集int i,add=1;for(i=1;i<k1;i++){if(x==pa[i].name){add=0;break;}}if(add){pa[k1].name=x;pa[k1].id=k1;k1++;}}void addpoint_b(char x,int &k2){//构造二分图的y点集int i,add=1;for(i=1;i<k2;i++){if(x==pb[i].name){add=0;break;}}if(add){pb[k2].name=x;pb[k2].id=k2;k2++;}}int searchx(char x,point p[]){for(int i=1;i<=g;i++){if(p[i].name==x)return p[i].id;}return -1;}int lx[N],ly[N],match[N],visx[N],visy[N],lack;int dfs(int x){//匈牙利visx[x]=1;for(int i=1;i<=g;i++){if(!visy[i] && lx[x]+ly[i]==map[x][i]){visy[i]=1;if(match[i]==-1 || dfs(match[i])){match[i]=x;return 1;}}}return 0;}int KM(){int i,j,k;for(i=1;i<=g;i++){//初始化顶标lx[i]=INT_MIN; ly[i]=0;for(j=1;j<=g;j++)lx[i]=max(map[i][j],lx[i]);}memset(match,-1,sizeof(match));for(i=1;i<=g;i++){while(1){//直到每个点都成功匹配,才结束循环memset(visx,0,sizeof(visx));memset(visy,0,sizeof(visy));if(dfs(i))break; //如果点 i 成功匹配,则不需要调整定标值/*------------顶标调整------------*/int lack=INT_MAX;//顶标调整值for(j=1;j<=g;j++){if(visx[j]){for(k=1;k<=g;k++){//取幅度最小的值为调整值if(!visy[k])lack=min(lx[j]+ly[k]-map[j][k],lack);}}}for(j=1;j<=g;j++){//调整已经得到匹配的点对的顶标值if(visx[j])lx[j]-=lack;if(visy[j])ly[j]+=lack;}/*---------------------------------*/}}int sum=0;for(i=1;i<=g;i++){if(match[i]!=-1)sum+=map[match[i]][i];}return sum;}void solve(){int i,j;char str[10010],ch[3];scanf("%d%d%d",&len,&g,&stu);int k1=1;for(i=1;i<=len;i++){scanf("%s",ch);str[i]=ch[0];addpoint_a(str[i],k1);}for(i=0;i<stu;i++){int k2=1;memset(map,0,sizeof(map));memset(pb,0,sizeof(pb));for(j=1;j<=len;j++){scanf("%s",ch);addpoint_b(ch[0],k2);int a=searchx(str[j],pa);int b=searchx(ch[0],pb);map[a][b]++;}int ans=KM();printf("%.4lf\n",ans*1.0/len);}}int main(){int t;scanf("%d",&t);while(t--){solve();}return 0;}
- HDU3718/ZOJ3425 Similarity(The 2010 ACM-ICPC Asia Chengdu Regional Contest,加权二分图的最优匹配)
- HDU3718ZOJ3425 Similarity(The 2010 ACM-ICPC Asia Chengdu Regional Contest,加权二分图的最优匹配)
- The 2010 ACM-ICPC Asia Chengdu Regional Contest
- zoj 3418 || The 2010 ACM-ICPC Asia Chengdu Regional Contest - C Binary Number
- 2-SAT——2.0(hdu3715 Go Deeper,The 2010 ACM-ICPC Asia Chengdu Regional Contest)
- HDU 4034 Graph The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest
- HDU 4038 Stone The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest
- 【转】The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest 出题报告
- The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest
- The 37th ACM/ICPC Asia Regional ChengDu Site Online Contest - B Control
- The 37th ACM/ICPC Asia Regional ChengDu Site Online Contest - F Groups
- HDOJ 4293暨The 37th ACM/ICPC Asia Regional ChengDu Site Online Contest - F Groups
- The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest题解
- The 2016 ACM-ICPC Asia Dalian Regional Contest(汇总)
- HDU 4033 4036 4039 The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest
- 2013 ACM/ICPC Asia Regional Chengdu Online
- 2013 ACM/ICPC Asia Regional Chengdu Online
- 2013 ACM/ICPC Asia Regional Chengdu Online
- 不经意的
- 收集一下核函数-Kernel Function
- 委托/事件/线程传参简单理解
- Bourne Shell C Shell Korn Shell POSIX Shell
- Excel 二级下拉菜单的3种方法
- HDU3718/ZOJ3425 Similarity(The 2010 ACM-ICPC Asia Chengdu Regional Contest,加权二分图的最优匹配)
- hibernate的核心配置中的一些常用配置
- 九连环的解法
- 37.最长字符串链接
- hdu 1754 I Hate It
- linux下好用的chm阅读器
- java面试题汇总
- sitemap生成工具,需要net框架支持
- C# 对象序列化成xml格式的时候指定日期型(DateTime)属性的序列化格式