HDU 3722 Card Game(二分图最佳完美匹配+KM算法)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3722

  1 /*
  2 问题
  3 将任意的两个字符串进行匹配,使得匹配后权值和最大
  4
  5 解题思路
  6 将任意的字符串的权值计算出来,使用KM算法即可。
  7 */
  8 #include<cstdio>
  9 #include<cstring>
 10 #include<algorithm>
 11 using namespace std;
 12
 13 const int maxn=210;
 14 int W[maxn][maxn],n;
 15 char s[maxn][1100];
 16 int lx[maxn],ly[maxn];
 17 int left[maxn];
 18 bool S[maxn],T[maxn];
 19 int len[maxn];
 20
 21 void presolve();
 22 int KM();
 23 bool match(int i);
 24 void update();
 25
 26 int main()
 27 {
 28     int i,j;
 29     while(scanf("%d",&n) != EOF)
 30     {
 31         for(i=1;i<=n;i++)
 32         {
 33             scanf("%s",s[i]);
 34             len[i]=strlen(s[i]);
 35         }
 36         presolve();
 37
 38         printf("%d\n",KM());
 39     }
 40 }
 41
 42 bool match(int i)
 43 {
 44     S[i]=true;
 45     for(int j=1;j<=n;j++) if(lx[i]+ly[j] == W[i][j] && !T[j]){
 46         T[j]=true;
 47         if(!left[j] || match(left[j])){
 48             left[j]=i;
 49             return true;
 50         }
 51     }
 52     return false;
 53 }
 54
 55 void update()
 56 {
 57     int a= 1<<30;
 58     for(int i=1; i<=n; i++){
 59         if(S[i]){
 60             for(int j=1;j<=n;j++){
 61                 if(!T[j]){
 62                     a = min(a,lx[i]+ly[j] - W[i][j]);
 63                 }
 64             }
 65         }
 66     }
 67
 68     for(int i=1;i<=n;i++){
 69         if(S[i])    lx[i] -= a;
 70         if(T[i])    ly[i] += a;
 71     }
 72 }
 73
 74 int KM()
 75 {
 76     for(int i=1;i<=n;i++){
 77         left[i] = lx[i] = ly[i] = 0;
 78         for(int j=1; j<=n; j++)
 79             lx[i]=max(lx[i],W[i][j]);
 80     }
 81
 82     for(int i=1; i<=n; i++){
 83         for(;;){
 84             for(int j=1;j<=n;j++){
 85                 S[j]=T[j]=0;
 86             }
 87             if(match(i)) break;
 88             else update();
 89         }
 90     }
 91
 92     int ans=0;
 93     for(int i=1;i<=n;i++)
 94         ans += W[left[i]][i];
 95     return ans;
 96 }
 97
 98 void presolve()
 99 {
100     int i,j,k,p1,p2,cnt;
101     for(i=1;i<=n;i++)
102     {
103         for(j=1;j<=n;j++)
104         {
105             if(i==j)
106             {
107                 W[i][j]=0;
108                 continue ;
109             }
110
111             cnt=0;
112             p1=len[i]-1;
113             p2=0;
114             while(1)
115             {
116                 if(s[i][p1]==s[j][p2]) cnt++;
117                 else break ;
118                 p1--,p2++;
119                 if(p1<0 || p2>=len[j]) break ;
120             }
121             W[i][j]=cnt;
122         }
123     }
124 }

原文地址:https://www.cnblogs.com/wenzhixin/p/9053758.html

时间: 2024-10-12 03:04:57

HDU 3722 Card Game(二分图最佳完美匹配+KM算法)的相关文章

HDU_2255 二分图最佳完美匹配 KM匈牙利算法

一开始还没看懂这个算法,后来看了陶叔去年的PPT的实例演示才弄懂 用一个lx[]和ly[]来记录X和Y集合中点的权值,有个定理是 lx[i]+ly[j]==w[i][j](边权值) 则该点是最佳匹配,因为首先 那个不等式肯定要>=的,否则就不满足题意了,如果是>则可以去匹配更有价值的边或者把权值降下来让匹配边的潜力更大. 所以只有把握了这个条件,其他就是走一遍最大匹配数.以及up()函数用来在无法匹配的时候,进行其他点的权值降低(也可以说是增广路的搜索)来得到匹配. #include <

UVa 11383 少林决胜(二分图最佳完美匹配)

https://vjudge.net/problem/UVA-11383 题意: 给定一个N×N矩阵,每个格子里都有一个正整数W(i,j).你的任务是给每行确定一个整数row(i),每列也确定一个整数col(i),使得对于任意格子(i,j),w(i,j)<=row(i)+col(j).所有的row(i)和col(i)只和应尽量小. 思路: 利用二分图最佳完美匹配当中的l(x)+l(y)>=w(i,j),直接用KM算法即可. 1 #include<iostream> 2 #inclu

UVA - 1045 The Great Wall Game(二分图最佳完美匹配)

题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include <cstdio> #include <cstring> #define N 20 #define INF 0x3f3f3f3f #define abs(x) ((x) > 0 ? (x) : (-(x))) #define max(a,b)((a)>(b)? (a):(b)) #

POJ 2195 二分图最小权匹配KM算法

本来是打算昨天晚上写的, 昨天网速渣的连CSDN都进不去,没办法 只能现在来写了 先写写对KM算法的理解,KM算法是对每个点设置一个顶标,只有当边长等于两边点的顶标之和的时候才进行增广,这样就能保证得到的一定是最大权匹配. 如果找不到匹配的时候就对交替路中X集合的顶标减少一个d Y集合的顶标增加一个d. 这样两个点都在交替路中的时候x[i]+y[i]的和不边 X在 Y不在的时候x[i]+y[i]减少,可能就会为图增加一对匹配. X不在Y在的时候x[i]+y[i]增加, 原来不在现在依然不在其中.

UVALive 4043 Ants 蚂蚁(二分图最佳完美匹配)

题意:n个蚂蚁n棵树,蚂蚁与树要配对,在配对成功的一对之间连一条线段,要求所有线段不能相交.按顺序输出蚂蚁所匹配的树. 思路:这个题目真是技巧啊,如果知道要求的就是整体最优,那么就容易做了.而不能用贪心来为每个蚂蚁选择最近的树,这样可能八成还是相交了. 整体最优能让每条线段不相交,证明: 假设a1-b1与a2-b2相交.则dis(a1,b1)+dis(a2,b2)>=dis(a1,b2)+dis(a2,b1).如果我们所决定的最优匹配是按照整体距离最短来匹配的,那么dis(a1,b1)+dis(

二分图 最大权匹配 km算法

这个算法的本质还是不断的找增广路: KM算法的正确性基于以下定理:若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配. 这个定理是显然的.因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和:如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和.所以相等子图的完备匹配一定是二分图的最大权匹配. (1)可行点标:每个点有一个标号,记lx[i]为X方点i的标号,l

poj 2195 Going Home 二分图最小权匹配KM算法

题意: 有n个人要回到n间房子里,每间房子只允许一个人,求n个人要走的最小距离和. 分析: 裸的二分图最小权匹配,KM搞之. 代码: //poj 2195 //sep9 #include <iostream> using namespace std; const int maxN=128; char g[maxN][maxN]; int mx[maxN],my[maxN],hx[maxN],hy[maxN]; int w[maxN][maxN]; int lx[maxN],ly[maxN],l

二分图最大权匹配(KM算法)

#80. 二分图最大权匹配 统计 描述 提交 自定义测试 从前一个和谐的班级,有 $n_l$ 个是男生,有 $n_r$ 个是女生.编号分别为 $1, \dots, n_l$ 和 $1, \dots, n_r$. 有若干个这样的条件:第 $v$ 个男生和第 $u$ 个女生愿意结为配偶,且结为配偶后幸福程度为 $w$. 请问这个班级里幸福程度之和最大是多少? 输入格式 第一行三个正整数,$n_l, n_r, m$. 接下来 $m$ 行,每行三个整数 $v, u, w$ 表示第 $v$ 个男生和第 $

hdu 2426 Interesting Housing Problem 最大权匹配KM算法

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2426 For any school, it is hard to find a feasible accommodation plan with every student assigned to a suitable apartment while keeping everyone happy, let alone an optimal one. Recently the president of