TOJ---1023---最小路径覆盖---
这应该算今天 噢 不对 都可以算昨天做的最有质量的一题了 至于什么是最小路径覆盖之类的 = 今天下午再说吧 有点累了
明天 又要上高数了 上学期 期末高数卷 必跪的节奏 。。。。
作妹啊 。。。。。。。。
先 给出链接 要是你也喜欢熬夜 今晚A了它吧
------------------- 以下可以 看成我的 碎碎念
碎觉了
全世界失眠 多好
你如果失眠了 应该感到开心 起码有人可以让你失眠
好久 不曾 失眠
今天 看到一句话
陪伴是最深情的告白
-----------------------以上 全与本文无关
嗯。。 应该怎么讲呢? 发现 我所写下的内容 还是只有我自己能看懂 作妹 。。。。。
最小路径覆盖 它也是二分图匹配中一个重要的概念的
我们对于它的求解 是将它从 有向图 -> 无向图
你可能会很奇怪 这怎么发生呢?
很简单 我们取有向图中的一个点 A 你应该清楚 每个顶点都有一个 入度 和 出度 的概念 我们可以看成A' A''
然后将它分成2个集合 来看 这样就很像我们以前接触的二分图了吧 左右 2个集合
可能 我们都知道 最小路径覆盖 = 顶点个数 - 二分图最大匹配
那 这个等式 为什么会成立呢?
我们想得到的最小的路径条数 那么是不是 得寻找一个边数最多的匹配方式 使尽量多的顶点连在一条路上 那么余下的顶点 就各自为一条路径
这里 你需要注意的是 一个顶点自身 即可以成为一条路径
可能 我这边讲的太简单了点 要是配个图 肯定理解起来更好 可是 我太 lazy 了
记得 对于它 是我和晓爷在 离散课上 圈圈画画 讨论出来的
你也可以去参考 一下大牛 博客 对它的理解
我这里 放上我的代码
1 // 极小路径覆盖 = N - 最大覆盖数 2 // x1 y1 x2 y2 ( x1 , y1 ) , ( x2 , y2 ) 3 #include <iostream> 4 #include <cstring> 5 #include <cstdio> 6 using namespace std; 7 8 const int size = 520; 9 struct data 10 { 11 int time; 12 int x1 , y1 , x2 , y2; 13 }car[size]; 14 bool vis[size]; 15 int linker[size]; 16 bool mp[size][size]; 17 int n; 18 19 int abs( int x ) 20 { 21 return x>0?x:-x; 22 } 23 24 bool judge( data p , data q ) 25 { 26 return p.time + abs(p.x2-p.x1) + abs(p.y2-p.y1) + abs(p.x2-q.x1) + abs(p.y2-q.y1 ) < q.time; //判断i j 是否可以相连 27 } 28 29 bool match( int u ) 30 { 31 for( int v = 0 ; v<n ; v++ ) 32 { 33 if( !vis[v] && mp[u][v] ) 34 { 35 vis[v] = true; 36 if( linker[v]==-1 || match( linker[v] ) ) 37 { 38 linker[v] = u; 39 return true; 40 } 41 } 42 } 43 return false; 44 } 45 46 int getSum() 47 { 48 int cnt = 0; 49 memset( linker , -1 , sizeof(linker) ); 50 for( int u = 0 ; u<n ; u++ ) 51 { 52 memset( vis , false , sizeof(vis) ); 53 if( match(u) ) 54 cnt++; 55 } 56 return cnt; 57 } 58 59 int main() 60 { 61 int t; 62 int i , j; 63 int h , m; 64 while( ~scanf("%d",&t) ) 65 { 66 while( t-- ) 67 { 68 memset( mp , false , sizeof(mp) ); 69 scanf( "%d",&n ); 70 for( i = 0 ; i<n ; i++ ) 71 { 72 scanf( "%d:%d %d %d %d %d",&h,&m,&car[i].x1,&car[i].y1,&car[i].x2,&car[i].y2 ); 73 car[i].time = 60*h + m; 74 } 75 for( i = 0 ; i<n ; i++ ) // 要是 可以在上一个地点结束后 来到下一地点 就可以看成 i j有边 可以连接起来 76 { 77 for( j = i+1 ; j<n ; j++ ) 78 { 79 if( judge( car[i] , car[j] ) ) 80 { 81 mp[i][j] = true; 82 } 83 } 84 } 85 printf( "%d\n",n-getSum() ); 86 } 87 } 88 return 0; 89 }
端午来了
学期要结束了
学妹们快要来了
离结束单身还远吗