POJ 2062

题意:两个人打牌,牌的大小按照2,3,4...9,T,J,Q,K,A排序,如果点数相等就按照H>S>D>C的花色排序。告诉你第一个人的手牌,让你安排第二个人的手牌,使得得分最大(按照顺序依次比较每张牌大小)

题解:先建立两人牌比较的二分图,就是第二个人的第i张牌如果比第一个人第j张牌大,就建立i->j的边,然后求一次二分匹配得答案。

View Code
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 using namespace std;

 5 bool g[30][30],chk[30];

 6 int link[30],n;

 7 bool findpath(int x)

 8 {

 9     for(int y=0;y<n;y++)

10     {

11         if(g[x][y]&&!chk[y])

12         {

13             chk[y]=true;

14             if(link[y]==-1||findpath(link[y]))

15             {

16                 link[y]=x;

17                 return true;

18             }

19         }

20     }

21     return false;

22 }

23 int maxmatch()

24 {

25     memset(link,-1,sizeof(link));

26     int ret=0;

27     for(int x=0;x<n;x++)

28     {

29         memset(chk,false,sizeof(chk));

30         if(findpath(x))

31             ret++;

32     }

33     return ret;

34 }

35 int op[150];

36 bool small(char s1[],char s2[])

37 {

38     if(op[s1[0]]!=op[s2[0]])

39         return op[s1[0]]<op[s2[0]];

40     else

41         return op[s1[1]]<op[s2[1]];

42 }

43 int main()

44 {

45     for(int i=2;i<=9;i++)

46         op[i+'0']=i;

47     op['T']=10;op['J']=11;op['Q']=12;op['K']=13;op['A']=14;

48     op['C']=1;op['D']=2;op['S']=3;op['H']=4;

49     int T;

50     for(scanf("%d",&T);T;T--)

51     {

52         scanf("%d",&n);

53         memset(g,false,sizeof(g));

54         char s1[30][3],s2[30][3];

55         for(int i=0;i<n;i++)

56             scanf("%s",s1[i]);

57         for(int i=0;i<n;i++)

58         {

59             scanf("%s",s2[i]);

60             for(int j=0;j<n;j++)

61                 if(small(s1[j],s2[i]))

62                     g[i][j]=true;

63         }

64         printf("%d\n",maxmatch());

65     }

66     return 0;

67 }

你可能感兴趣的:(poj)