码迷,mamicode.com
首页 > 其他好文 > 详细

Swap HDU - 2819

时间:2021-01-25 11:35:38      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:i++   style   int   二分   net   dfs   type   it!   first   

原题链接

考察:二分图匹配+线性代数(?)

完全是参考大佬的思路:

       根据线性代数的知识,如果矩阵的对角线全为1,说明该矩阵的秩是满的,而初等变换(交换行或者列)不改变矩阵的秩,因此行变换可由列变换代替,其实这道题感觉是在求矩阵的秩,行列变换同时进行会改变矩阵的秩,因此这道题只用行变换或者列变换即可

关键是如何建立二分图:

      根据前面的题很容易想到是横坐标一个集合,纵坐标一个集合.我们要求每一行上都有1,也就是把第i行的1交换到第i列.因此两集合的关系就出来了,将i行指向该行的所有1,边的意义就是将该行的1换到第i列.

关于最后交换swap:

       我们找到与i匹配的match[j]后,实际上是交换了第j列和第i列.原来指向第j列的也要发生改变.实在不能理解可在纸上模拟

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <set>
 5 using namespace std;
 6 typedef pair<int,int> pii;
 7 const int N = 110;
 8 int match[N*N],n,mp[N][N];
 9 bool st[N*N],g[N][N];
10 set<pii> s;
11 void inits()
12 {
13     memset(match,0,sizeof match);
14     memset(g,0,sizeof g); s.clear();
15 }
16 bool dfs(int x)
17 {
18     for(int i=1;i<=n;i++)
19     {
20         if(!g[x][i]||st[i]) continue;
21         st[i] = 1;
22         if(!match[i]||dfs(match[i]))
23         {
24             match[i] = x;
25             return true;
26         }
27     }
28     return false;
29 }
30 int main()
31 {
32 //    freopen("in.txt","r",stdin);
33     while(scanf("%d",&n)!=EOF)
34     {
35         inits();
36         int res = 0;
37         for(int i=1;i<=n;i++)
38           for(int j=1;j<=n;j++)
39           {
40             scanf("%d",&mp[i][j]);
41             if(mp[i][j]) g[i][j] = 1;
42           }
43         for(int i=1;i<=n;i++)
44         {
45             memset(st,0,sizeof st);
46             if(dfs(i)) res++;
47         }
48         if(res!=n) puts("-1");
49         else{
50             for(int i=1;i<=n;i++)
51               if(match[i]!=i)
52               {
53                   for(int j=1;j<=n;j++)
54                   {
55                         if(i==match[j])
56                         {
57                             s.insert({i,j});
58                             swap(match[i],match[j]);//原来的第i列变成了第j列 
59                     }
60                 }
61               }
62             printf("%d\n",s.size());
63             for(auto it=s.begin();it!=s.end();it++) printf("C %d %d\n",it->first,it->second);
64         }
65     }
66     return 0;
67 } 

 

Swap HDU - 2819

标签:i++   style   int   二分   net   dfs   type   it!   first   

原文地址:https://www.cnblogs.com/newblg/p/14319226.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!