zoukankan      html  css  js  c++  java
  • HDOJ1151解题报告【有向图的最小路径覆盖】

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1151

    题目概述:

      一座城市有n个路口和m条有向路径,题目保证没有环,现在派一些伞兵去巡查城市,求最少需要多少伞兵才能走遍所有路口。

    大致思路:

      刚开始的时候是有些懵逼的,后来看了一下网上大神的题解,发现这个题是求DAG的最小路径覆盖,就等于顶点数-最大匹配数。

      将DAG转化为二分图的方法是如果有一条p->q的边,那么在二分图中加入p-q之间的无向边,其中p在集合S,q在集合T。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <vector>
     6 #include <ctime>
     7 #include <map>
     8 #include <queue>
     9 #include <cstring>
    10 #include <algorithm>
    11 using namespace std;
    12 
    13 #define sacnf scanf
    14 #define scnaf scanf
    15 #define maxn 310
    16 #define maxm 26
    17 #define inf 1061109567
    18 #define Eps 0.00001
    19 const double PI=acos(-1.0);
    20 #define mod 7
    21 #define MAXNUM 10000
    22 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
    23 double Abs(double x) {return (x<0)?-x:x;}
    24 typedef long long ll;
    25 typedef unsigned int uint;
    26 
    27 int n,m;
    28 vector<int> G[maxn];
    29 int vis[maxn],l[maxn];
    30 
    31 bool dfs(int u)
    32 {
    33     int len=G[u].size();
    34     for(int i=0;i<len;i++)
    35     {
    36         int v=G[u][i];
    37         if(!vis[v])
    38         {
    39             vis[v]=1;
    40             if(l[v]==-1||dfs(l[v]))
    41             {
    42                 l[v]=u;return true;
    43             }
    44         }
    45     }
    46     return false;
    47 }
    48 
    49 int hungary()
    50 {
    51     int cnt=0;
    52     memset(l,-1,sizeof(l));
    53     for(int i=1;i<=n;i++)
    54     {
    55         memset(vis,0,sizeof(vis));
    56         if(dfs(i)) cnt++;
    57     }
    58     return cnt;
    59 }
    60 
    61 int main()
    62 {
    63     //freopen("data.in","r",stdin);
    64     //freopen("data.out","w",stdout);
    65     //clock_t st=clock();
    66     int T,a,b;scnaf("%d",&T);
    67     while(T--)
    68     {
    69         scanf("%d%d",&n,&m);
    70         for(int i=1;i<=n*2;i++) G[i].clear();
    71         for(int i=1;i<=m;i++)
    72         {
    73             scanf("%d%d",&a,&b);
    74             G[a].push_back(n+b);
    75             G[n+b].push_back(a);
    76         }
    77         int ans=hungary();
    78         printf("%d
    ",n-ans);
    79     }
    80     //clock_t ed=clock();
    81     //printf("
    
    Time Used : %.5lf Ms.
    ",(double)(ed-st)/CLOCKS_PER_SEC);
    82     return 0;
    83 }
  • 相关阅读:
    php 获取当前目录和当前文件夹
    学习笔记12(选做)
    学习笔记11
    OpenEuler 中C与汇编的混合编程
    OpenEuler中C语言中的函数调用测试
    学习笔记10
    电子公文传输系统验收3开发环境
    电子公文传输系统验收2功能测试
    socket编程
    socket课堂
  • 原文地址:https://www.cnblogs.com/CtrlKismet/p/6510605.html
Copyright © 2011-2022 走看看