• hdu 3861(缩点+最小路径覆盖)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861

    思路:缩点是显然的:What’s more, for each pair of city (u, v), if there is one way to go from u to v and go from v to u, (u, v) have to belong to a same state.然后就是建新图了,求最大匹配即可。

    这里有最小路径覆盖==|顶点个数|-最大匹配;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<stack>
     7 using namespace std;
     8 #define MAXN 5555
     9 vector<int>vet[MAXN];//原图
    10 vector<int>map[MAXN];//缩点后的图
    11 stack<int>S;
    12 bool mark[MAXN];//标记元素是否在栈中
    13 int color[MAXN];//缩点,染色
    14 int n,m,cnt,_count;
    15 int dfn[MAXN],low[MAXN];
    16 int lx[MAXN],ly[MAXN];
    17 bool visited[MAXN];
    18 
    19 //求有向图的强联通分量
    20 void Tarjan(int u){
    21    dfn[u]=low[u]=++cnt;
    22    mark[u]=true;
    23    S.push(u);
    24    for(int i=0;i<vet[u].size();i++){
    25       int v=vet[u][i];
    26       //没访问过
    27       if(dfn[v]==0){
    28          Tarjan(v);
    29          low[u]=min(low[u],low[v]);
    30       }else if(mark[v]){ low[u]=min(low[u],dfn[v]); }
    31    }
    32    if(low[u]==dfn[u]){
    33       int v;
    34       do{
    35          v=S.top();
    36          S.pop();
    37          mark[v]=false;
    38          color[v]=_count;//缩点,染色
    39       }while(u!=v);
    40       _count++;
    41    }
    42 }
    43 
    44 
    45 int dfs(int u){
    46    for(int i=0;i<map[u].size();i++){
    47       int v=map[u][i];
    48       if(!visited[v]){
    49          visited[v]=true;
    50          if(ly[v]==-1||dfs(ly[v])){ ly[v]=u;lx[u]=v;return 1; }
    51       }
    52    }
    53    return 0;
    54 }
    55 
    56 
    57 int MaxMatch(){
    58    int res=0;
    59    memset(lx,-1,sizeof(lx));
    60    memset(ly,-1,sizeof(ly));
    61    for(int i=0;i<_count;i++){
    62       memset(visited,false,sizeof(visited));
    63       if(lx[i]==-1)res+=dfs(i);
    64    }
    65    return res;
    66 }
    67 
    68 int main(){
    69    int _case,u,v;
    70    scanf("%d",&_case);
    71    while(_case--){
    72       scanf("%d%d",&n,&m);
    73       for(int i=1;i<=n;i++){ vet[i].clear();map[i].clear(); }
    74       for(int i=1;i<=m;i++){
    75          scanf("%d%d",&u,&v);
    76          vet[u].push_back(v);
    77       }
    78       memset(mark,false,sizeof(mark));
    79       memset(dfn,0,sizeof(dfn));
    80       memset(low,0,sizeof(low));
    81       memset(color,0,sizeof(color));
    82       _count=cnt=0;
    83       for(int i=1;i<=n;i++)if(dfn[i]==0)Tarjan(i);
    84       for(int i=1;i<=n;i++){
    85          for(int j=0;j<vet[i].size();j++){
    86             if(color[i]!=color[vet[i][j]]){
    87                map[color[i]].push_back(color[vet[i][j]]);
    88             }
    89          }
    90       }
    91       int ans=MaxMatch();
    92       printf("%d\n",_count-ans);
    93    }
    94    return 0;
    95 }
    View Code
  • 相关阅读:
    h5之js生成二维码
    h5手势密码开发(使用jq)
    html可用于跨域的三个标签
    原生js实现ajax
    js中parentNode,parentElement,childNodes,children
    js字符串操作之substr与substring
    pyhton之os.path
    [bzoj1510][POI2006]Kra-The Disks_暴力
    [bzoj4994][Usaco2017 Feb]Why Did the Cow Cross the Road III_树状数组
    [bzoj2506]calc_分块处理
  • 原文地址:https://www.cnblogs.com/wally/p/3112074.html
Copyright © 2020-2023  润新知