Card Game(网络流,KM)

                                                                     Card Game



题目链接:Click Here~

题目分析:

     给你n张卡片,每张卡片上都有一串字母,问你如何链接卡片使得最后的得分最多。卡片自己可以连接自己。得分的标准是如果链接两种卡片s1,s2的时候,最终的得分是将s1反转看其跟s2的前缀有多上个相同的字母,有几个相同的字母就表示s1->s2可以得到的分数。

For example, there are 3 cards, whose strings are S1="ab", S2="bcc", S3="ccb". There are 6 possible sticking:
1.  S1->S2, S2->S3, S3->S1, the score is 1+3+0 = 4
2.  S1->S2, S2->S1, S3->S3, the score is 1+0+0 = 1
3.  S1->S3, S3->S1, S2->S2, the score is 0+0+0 = 0
4.  S1->S3, S3->S2, S2->S1, the score is 0+3+0 = 3
5.  S1->S1, S2->S2, S3->S3, the score is 0+0+0 = 0
6.  S1->S1, S2->S3, S3->S2, the score is 0+3+3 = 6
So the best score is 6.


算法分析:

   这是一道2010年的区域赛题,出的很严谨。一开始可能没感觉,但是当你越推敲他的时候发现其给出的条件越多。这题其实就是标准的完全匹配的最大权值问题。因为,题目给出了很多小的暗示,表示肯定可以达到完美匹配。感兴趣的可以自己认真读题。虽然做了几道KM算法题,但是还是对其原理本质很模糊啊。要继续努力,加油! ^_^

 

建模分析:

   既然知道了是标准的完全匹配问题了,建图就应该没什么难得了。但是一开始我还是建错了冏。。。后来重复的看代码才发现了错误。一开还以为要拆点,后来发现只要有联系的两个点连线就好了,这其实题目也有给出了说明,就是自己可以链接自己,每两个字符都可以连接。建完图之后,就是KM算法的问题了。


#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int INF = ~0U >> 2;
const int MAXN = 200 + 5;
int n,graph[MAXN][MAXN];
int slack,Lx[MAXN],Ly[MAXN],Link[MAXN];
bool S[MAXN],T[MAXN];
char str[MAXN][1002];
int Get(char *str1,char *str2)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int i = len1-1,j = 0;
    while(i>=0&&j

  









你可能感兴趣的:(Card Game(网络流,KM))