1. 程式人生 > >LA 3126 出租車

LA 3126 出租車

tar -a ace 意思 vector uvalive pla 覆蓋 技術

題目鏈接:https://vjudge.net/problem/UVALive-3126

題意:有m個客人,位於不同的位置,去一些地方,出發的時間給出,要一些出租車去接,但是,每輛出租車要在出發前一分鐘要到,問:最少要幾輛出租車;

分析:最少路徑覆蓋(在圖中找盡量少的路徑,使得每個節點恰好在一條路徑上)

建圖: 一個點拆成 i i‘,i->j 就連一條邊到 j‘;

答案是 n - 最大匹配;

證明:之前有證明過,很有意思;

這裏,就是從一個接完客人到另下一個客人,是否可以接到,能就連一條邊;

技術分享
 1 #include <cstdio>
 2 #include <cstring>
 3
#include <vector> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 500 + 5; // 單側頂點的最大數目 8 9 struct BPM { 10 int n,m; 11 vector<int> G[maxn]; 12 int left[maxn]; 13 bool T[maxn]; 14 15 int right[maxn]; 16 bool S[maxn]; 17 18
void init(int n,int m) { 19 this->n = n; 20 this->m = m; 21 for(int i=0; i<n; i++) 22 G[i].clear(); 23 } 24 25 void AddEdge(int u,int v) { 26 G[u].push_back(v); 27 } 28 29 bool match(int u) { 30 S[u] = true;
31 for(int i=0; i<G[u].size(); i++) { 32 int v = G[u][i]; 33 if(!T[v]) { 34 T[v] = true; 35 if(left[v]==-1||match(left[v])) { 36 left[v] = u; 37 right[u] = v; 38 return true; 39 } 40 } 41 } 42 return false; 43 } 44 45 int solve() { 46 memset(left,-1,sizeof(left)); 47 memset(right,-1,sizeof(right)); 48 int ans = 0; 49 for(int u=0; u<n; u++) { 50 memset(S,0,sizeof(S)); 51 memset(T,0,sizeof(T)); 52 if(match(u)) 53 ans++; 54 } 55 return ans; 56 } 57 58 } sol; 59 60 61 int x1[maxn], y1[maxn], x2[maxn], y2[maxn], t1[maxn], t2[maxn]; 62 63 int dist(int a, int b, int c, int d) { 64 return abs(a-c) + abs(b-d); 65 } 66 67 int main() { 68 int T; 69 scanf("%d", &T); 70 while(T--) { 71 int n; 72 scanf("%d", &n); 73 for(int i = 0; i < n; i++) { 74 int h, m; 75 scanf("%d:%d%d%d%d%d", &h, &m, &x1[i], &y1[i], &x2[i], &y2[i]); 76 t1[i] = h*60+m; 77 t2[i] = t1[i] + dist(x1[i], y1[i], x2[i], y2[i]); 78 } 79 sol.init(n, n); 80 for(int i = 0; i < n; i++) 81 for(int j = i+1; j < n; j++) 82 if(t2[i] + dist(x2[i], y2[i], x1[j], y1[j]) < t1[j]) 83 sol.AddEdge(i,j); 84 printf("%d\n", n - sol.solve()); 85 } 86 return 0; 87 }
View Code

LA 3126 出租車