zoukankan      html  css  js  c++  java
  • poj 3041( 最大匹配)

    题意:给出一个矩阵和一些矩阵上的点,选择最少的行或列把给出的点覆盖。

    思路:把行看成一个点集,列看成另一个点集,每个给出点构造一条这两个点集中的一条边。我们的问题就变成了选择最少的点把所有的边覆盖。很显然这就是一个最大独立点集问题,可用最大匹配求解。

    匈牙利匹配算法:

    View Code
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 using namespace std;
     5 #define N 10010
     6 #define M 20020
     7 struct edge{
     8     int to,next;
     9 }e[M];
    10 int pre[N],visit[N],p[N];
    11 int cnt;
    12 void add(int a,int b)
    13 {
    14     e[cnt].next=pre[a];
    15     e[cnt].to=b;
    16     pre[a]=cnt++;
    17 }
    18 bool dfs(int u)
    19 {
    20     for(int edg=pre[u];edg!=0;edg=e[edg].next)
    21     {
    22         int v=e[edg].to;
    23         if(visit[v])continue;
    24         visit[v]=1;
    25         if(!p[v]||dfs(p[v]))
    26         {
    27             p[v]=u;
    28             return true;
    29         }
    30     }
    31     return false;
    32 }
    33 int main()
    34 {
    35     int n,m;
    36     while(scanf("%d%d",&n,&m)!=EOF)
    37     {
    38         cnt=1;
    39         int c=0;
    40         memset(p,0,sizeof(p));
    41         memset(pre,0,sizeof(pre));
    42         for(int i=1;i<=m;i++){
    43             int a,b;
    44             scanf("%d%d",&a,&b);
    45             add(a,b+n);
    46             add(b+n,a);
    47         }
    48 
    49         for(int i=1;i<=n;i++)
    50         {
    51             memset(visit,0,sizeof(visit));
    52             if(dfs(i))c++;
    53         }
    54         printf("%d\n",c);
    55     }
    56     return 0;
    57 }

    最大流dinic算法(邻接矩阵实现):

    View Code
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 using namespace std;
     5 #define inf 0x3f3f3f3f
     6 #define N 1010
     7 int S,T,L,R;
     8 int flow[N][N],cap[N][N],level[N],q[N];
     9 bool dinic_bfs()
    10 {
    11     int rear=0,tail=1;
    12     q[0]=S;
    13     memset(level,0,sizeof(level));
    14     level[S]=1;
    15     while(rear<tail)
    16     {
    17         int u=q[rear++];
    18         for(int i=L;i<=R;i++)
    19         {
    20             if(!level[i]&&cap[u][i]-flow[u][i]>0)
    21             {
    22                 level[i]=level[u]+1;
    23                 q[tail++]=i;
    24             }
    25         }
    26     }
    27     return level[T]!=0;
    28 }
    29 int dinic_dfs(int u,int cp)
    30 {
    31     int tmp=cp;
    32     if(u==T)return cp;
    33     for(int i=L;i<=R&&tmp;i++)
    34     {
    35         if(level[i]==level[u]+1&&cap[u][i]-flow[u][i]>0)
    36         {
    37             int t=dinic_dfs(i,min(tmp,cap[u][i]-flow[u][i]));
    38             flow[u][i]+=t;
    39             flow[i][u]-=t;
    40             tmp-=t;
    41         }
    42     }
    43     return cp-tmp;
    44 }
    45 int dinic()
    46 {
    47     int tf=0,f;
    48     while(dinic_bfs())
    49     {
    50         while(f=dinic_dfs(S,inf))
    51         {
    52             tf+=f;
    53         }
    54     }
    55     return tf;
    56 }
    57 int main()
    58 {
    59     int n,m;
    60     while(scanf("%d%d",&n,&m)!=EOF)
    61     {
    62         memset(flow,0,sizeof(flow));
    63         memset(cap,0,sizeof(cap));
    64         S=L=0;
    65         T=R=2*n+1;
    66         for(int i=1;i<=m;i++)
    67         {
    68             int a,b;
    69             scanf("%d%d",&a,&b);
    70             cap[a][b+n]=1;
    71         }
    72         for(int i=1;i<=n;i++)
    73         {
    74             cap[S][i]=1;
    75             cap[i+n][T]=1;
    76         }
    77         printf("%d\n",dinic());
    78     }
    79     return 0;
    80 }

    最大流dinic算法(邻接表实现):

    View Code
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 using namespace std;
     5 #define N 1010
     6 #define M 20020
     7 #define inf 0x3f3f3f3f
     8 struct edge{
     9     int to,next,cap,flow;
    10 }e[M];
    11 int pre[N],level[N],q[N];
    12 int cnt,S,T;
    13 void add(int a,int b,int c)
    14 {
    15     e[cnt].to=b;
    16     e[cnt].next=pre[a];
    17     e[cnt].cap=c;
    18     e[cnt].flow=0;
    19     pre[a]=cnt++;
    20 }
    21 bool dinic_bfs()
    22 {
    23     int rear=0,tail=1;
    24     q[0]=S;
    25     memset(level,0,sizeof(level));
    26     level[S]=1;
    27     while(rear<tail)
    28     {
    29         int u=q[rear++];
    30         for(int edg=pre[u];edg!=0;edg=e[edg].next)
    31         {
    32             int v=e[edg].to;
    33             if(!level[v]&&e[edg].cap>e[edg].flow)
    34             {
    35                 level[v]=level[u]+1;
    36                 q[tail++]=v;
    37             }
    38         }
    39     }
    40     return level[T]!=0;
    41 }
    42 int dinic_dfs(int u,int cp)
    43 {
    44     int tmp=cp;
    45     if(u==T)return cp;
    46     for(int edg=pre[u];tmp&&edg!=0;edg=e[edg].next)
    47     {
    48         int v=e[edg].to;
    49         if(level[v]==level[u]+1&&e[edg].cap>e[edg].flow)
    50         {
    51             int t=dinic_dfs(v,min(tmp,e[edg].cap-e[edg].flow));
    52             e[edg].flow+=t;
    53             e[edg^1].flow-=t;
    54             tmp-=t;
    55         }
    56     }
    57     return cp-tmp;
    58 }
    59 int dinic()
    60 {
    61     int tf=0,f;
    62     while(dinic_bfs())
    63     {
    64         //cout<<1<<endl;
    65         while(f=dinic_dfs(S,inf))
    66         {
    67             //cout<<f<<endl;
    68             tf+=f;
    69         }
    70     }
    71     return tf;
    72 }
    73 int main()
    74 {
    75     int n,m;
    76     while(scanf("%d%d",&n,&m)!=EOF)
    77     {
    78         memset(pre,0,sizeof(pre));
    79         int cnt=2;
    80         S=0;T=2*n+1;
    81         for(int i=1;i<=m;i++)
    82         {
    83             int a,b;
    84             scanf("%d%d",&a,&b);
    85             add(a,b+n,1);
    86             add(b+n,a,0);
    87         }
    88         for(int i=1;i<=n;i++)
    89         {
    90             add(S,i,1);
    91             add(i,S,0);
    92             add(i+n,T,1);
    93             add(T,i+n,0);
    94         }
    95         printf("%d\n",dinic());
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    软件工程的国家标准下载链接
    电子计算机机房设计规范
    建筑物防雷设计规范
    信息系统项目管理师考试大纲
    计算机信息系统安全保护等级划分准则
    信息系统工程监理单位资质管理办法
    信息系统工程监理工程师资格管理办法
    计算机软件保护条例
    信息系统工程监理暂行规定
    第一个Winform 程序 (附一个需求实现,望大家帮忙)
  • 原文地址:https://www.cnblogs.com/huangriq/p/2482655.html
Copyright © 2011-2022 走看看