hdu 2819 记录路径的二分匹配

题目大意就是给出一个矩阵,每个格子里面要么是0, 要么是1;是否能够经过交换(交换行或者列)使得主对角线上都是1。

其实就行和列的匹配,左边是行,右边是列,然后如果行列交点是1,那么就可以匹配,看是否为完美匹配,然后输出怎么交换的。开始很蒙的,后来仔细去 想,可以这样理解,想要对角线上都是1,那么我们就可以锁定行,来选择列和它匹配,将选择的列移动到和该行形成对角线上是1的位置,比如和第一行匹配的 列,就要移动要第一列,第二行的,就到第二列。其实就是对第i行,找一个第i个数是1的列和它匹配,然后看是否是最大匹配!

路径的输出其实就是 调整匹配使之都为横线,调整的过程就是要输出的路径,调整列和行是相同的,所以锁定一个方向就行了

Sample Input

2
0 1
1 0
2
1 0
1 0
Sample Output
1

R 1 2

-1

2015-05-14:
 1 #include<cstdio>

 2 #include<iostream>

 3 #include<algorithm>

 4 #include<cstring>

 5 #include<cmath>

 6 #include<queue>

 7 #include<map>

 8 using namespace std;

 9 #define MOD 1000000007

10 const int INF=0x3f3f3f3f;

11 const double eps=1e-5;

12 typedef long long ll;

13 #define cl(a) memset(a,0,sizeof(a))

14 #define ts printf("*****\n");

15 int n,m,tt;

16 const int MAXN = 510;

17 int a[10000],b[10000];

18 int uN,vN;//u,v的数目,使用前面必须赋值

19 int g[MAXN][MAXN];//邻接矩阵

20 int linker[MAXN];

21 bool used[MAXN];

22 bool dfs(int u)

23 {

24     for(int v = 0; v < vN;v++)

25     if(g[u][v] && !used[v])

26     {

27         used[v] = true;

28         if(linker[v] == -1 || dfs(linker[v]))

29         {

30             linker[v] = u;

31             return true;

32         }

33     }

34     return false;

35 }

36 int hungary()

37 {

38     int res = 0;

39     memset(linker,-1,sizeof(linker));

40     for(int u = 0;u < uN;u++)

41     {

42         memset(used,false,sizeof(used));

43         if(dfs(u))res++;

44     }

45     return res;

46 }

47 int main()

48 {

49     int i,j,k;

50     #ifndef ONLINE_JUDGE

51     freopen("1.in","r",stdin);

52     #endif

53     while(scanf("%d",&n)!=EOF)

54     {

55         uN=vN=n;

56         for(i=0;i<n;i++)

57             for(j=0;j<n;j++)    scanf("%d",&g[i][j]);

58         int ans=hungary();

59         if(ans<n)

60         {

61             printf("-1\n");

62             continue;

63         }

64         int res=0;

65         for(i=0;i<n;i++)

66         {

67             for(j=0;j<n;j++)

68             {

69                 if(linker[j]==i)    break;

70             }

71             if(i!=j)

72             {

73                 a[res]=i,b[res++]=j;

74                 int temp=linker[j];

75                 linker[j]=linker[i];

76                 linker[i]=temp;

77             }

78         }

79         printf("%d\n",res);

80         for(i=0;i<res;i++)

81         {

82             printf("C %d %d\n",a[i]+1,b[i]+1);

83         }

84     }

85 }

 

 

你可能感兴趣的:(HDU)