zoukankan      html  css  js  c++  java
  • UVAlive3126 Taxi Cab Scheme(DAG的最小路径覆盖)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32568

    【思路】

           DAG的最小路径覆盖。

           将每个人看做一个结点,如果时间允许到达就连边,则问题转化为DAG上的最小路径覆盖问题,即找到最少的路径使得每个点位于一条路径上。

           算法:将DAG中的每个结点u拆分成2个为u1,u2,如果DAG中有边uv则连边u1-v2。如果该二分图的最大匹配数为ans,则答案为n-ans。可以这样想:在一条路径中除尾结点外其他结点都有且仅有一个后缀结点,把一个匹配看作成功找到一个后缀结点,则匹配数最大化即为尾结点最小化,即为路径数最小化。

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 const int maxn =  1000+10;
     9 
    10 bool T[maxn];
    11 int lky[maxn];
    12 vector<int> G[maxn];
    13 
    14 bool match(int u) {
    15     for(int i=0;i<G[u].size();i++) {
    16         int v=G[u][i];
    17         if(!T[v]) {
    18             T[v]=1;
    19             if(!lky[v] || match(lky[v])) {
    20                 lky[v]=u;
    21                 return true;
    22             }
    23         }
    24     }
    25     return false;
    26 }
    27 
    28 int n;
    29 int tsta[maxn],tend[maxn],ex[maxn],ey[maxn],sx[maxn],sy[maxn];
    30 
    31 int dist(int i,int j) {  
    32     return abs(sx[j]-ex[i])+abs(sy[j]-ey[i]);
    33 }
    34 
    35 int main() {
    36     int K;
    37     scanf("%d",&K);
    38     while(K--) {
    39         scanf("%d",&n);
    40         for(int i=1;i<=n;i++) G[i].clear();
    41         for(int i=1;i<=n;i++) {
    42             char s[10]; scanf("%s",s);
    43             tsta[i]=((s[0]-'0')*10+(s[1]-'0'))*60+((s[3]-'0')*10+(s[4]-'0'));
    44             scanf("%d%d%d%d",&sx[i],&sy[i],&ex[i],&ey[i]);
    45             tend[i]=tsta[i]+dist(i,i);
    46         }
    47         for(int i=1;i<=n;i++)
    48             for(int j=1;j<=n;j++) if(i!=j) {
    49                 if(tend[i]+dist(i,j)+1 <= tsta[j])
    50                     G[i].push_back(j);
    51             }
    52         memset(lky,0,sizeof(lky));
    53         int ans=0;
    54         for(int i=1;i<=n;i++) {
    55             memset(T,0,sizeof(T));
    56             if(match(i)) ans++;
    57         }
    58         printf("%d
    ",n-ans);
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    Django
    闭包&装饰器
    Python学习 Day 062
    Python学习 Day 059
    Python学习 Day 058
    Python生成器
    第一类对象(函数),闭包及迭代器
    进阶函数的学习
    对函数的初步了解
    python文件操作
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5077539.html
Copyright © 2011-2022 走看看