zoukankan      html  css  js  c++  java
  • Plug It In

    Plug It In

     

     

     题意:有(m)个插座,(n)个电设备,每个插座可以插特定的几个电设备,每个电设备也可以配特定的几个插座,现在又一个插线板可以选择其中的一个插座让它变成(3)个,求最大匹配数

    分析很明显二分图匹配,如果没有插线板,那么匈牙利算法跑一遍就可以了,如果说把每一种插座都插插线板跑二分图,就会超时。

    其实可以先不考虑插线板,跑一次二分图,然后对n种插座都插插线板,把插线板插在i插座上,就相当于再找两次增广路,如果能够找到,就在原先匹配上++

    AC_Code:

     1 #include <iostream>
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=75010;
     6 const double inf=9999999999.9;
     7 const int mod=1e9+7;
     8 #define rep(i,first,second) for(int i=first;i<=second;i++)
     9 #define dep(i,first,second) for(int i=first;i>=second;i--)
    10 
    11 int mat[1510],match[1510],in[1510],vis[1510];
    12 vector<int>gra[maxn];
    13 int n,m,k;
    14 
    15 void getMap(){
    16     memset(match,0,sizeof(match));
    17     memset(in,0,sizeof(in));
    18     scanf("%d%d%d",&m,&n,&k);
    19     rep(i,1,k){
    20         int u,v;
    21         scanf("%d%d",&u,&v);
    22         gra[u].push_back(v);
    23         in[u]++;
    24     }
    25 }
    26 
    27 int dfs(int x){
    28     for(int i=0;i<gra[x].size();i++){
    29         int v=gra[x][i];
    30         if(!vis[v]){
    31             vis[v]=1;
    32             if( match[v]==0||dfs(match[v])){
    33                 match[v]=x;
    34                 return 1;
    35             }
    36         }
    37     }
    38     return 0;
    39 }
    40 
    41 
    42 int Hungray(){
    43     int ans=0;
    44     rep(i,1,m){
    45         memset(vis,0,sizeof(vis));
    46         ans+=dfs(i);
    47     }
    48     return ans;
    49 }
    50 
    51 int main()
    52 {
    53     getMap();
    54     int ans=Hungray();
    55     rep(i,1,n){
    56         mat[i]=match[i];//保存不考虑插线板的时候的匹配情况
    57     }
    58     int x=0,mmax=0;
    59     rep(i,1,n){
    60         if(in[i]>1){
    61             rep(j,1,n) match[j]=mat[j];
    62             rep(j,m+1,m+2){//增加两个
    63                 gra[j].clear();
    64                 for(int q=0;q<gra[i].size();q++){
    65                     gra[j].push_back(gra[i][q]);
    66                 }
    67             }
    68             x=0;
    69             memset(vis,0,sizeof(vis));
    70             x+=dfs(m+1);
    71             memset(vis,0,sizeof(vis));
    72             x+=dfs(m+2);
    73             mmax=max(mmax,x);
    74             if( mmax==2 ) break;
    75         }
    76     }
    77     ans+=mmax;
    78     printf("%d
    ",ans);
    79     return 0;
    80 }
    邻接矩阵
     1 #include <iostream>
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=75010;
     6 const double inf=9999999999.9;
     7 const int mod=1e9+7;
     8 #define rep(i,first,second) for(int i=first;i<=second;i++)
     9 #define dep(i,first,second) for(int i=first;i>=second;i--)
    10 #define erep(i,u) for(int i=head[u];~i;i=e[i].nxt)
    11 
    12 struct edge{int to,nxt;}e[maxn];
    13 int head[1510],tot;
    14 int match[1510],vis[1510],mat[1510];
    15 int n,m,k;
    16 
    17 void add(int u,int v){
    18     e[tot].to=v;
    19     e[tot].nxt=head[u];
    20     head[u]=tot++;
    21 }
    22 
    23 int dfs(int u){
    24     erep(i,u){
    25         int v=e[i].to;
    26         if( !vis[v] ){
    27             vis[v]=1;
    28             if( match[v]==0 || dfs(match[v])){
    29                 match[v]=u;
    30                 return 1;
    31             }
    32         }
    33     }
    34     return 0;
    35 }
    36 
    37 int Hungray(){
    38     int ans=0;
    39     rep(i,1,m){
    40         memset(vis,0,sizeof(vis));
    41         ans+=dfs(i);
    42     }
    43     return ans;
    44 }
    45 
    46 void init(){
    47     tot=0;
    48     memset(head,-1,sizeof(head));
    49     memset(match,0,sizeof(match));
    50 }
    51 
    52 int main()
    53 {
    54     ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    55     init();
    56     scanf("%d%d%d",&m,&n,&k);
    57     rep(i,1,k){
    58         int u,v;
    59         scanf("%d%d",&u,&v);
    60         add(u,v);
    61     }
    62     int ans=Hungray();
    63 
    64     rep(i,1,n) mat[i]=match[i];
    65     int x=0,maxx=0;
    66     rep(i,1,m){                 //注意与邻接矩阵的不同之处(还不知道为什么)
    67         rep(j,1,n) match[j]=mat[j];
    68         x=0;
    69         rep(j,1,2){
    70             memset(vis,0,sizeof(vis));
    71             if( dfs(i) ) x++;
    72             else break;
    73         }
    74         maxx=max(maxx,x);
    75     }
    76     ans+=maxx;
    77     printf("%d
    ",ans);
    78     return 0;
    79 }
    前向星邻接表
  • 相关阅读:
    快速入门各种跨域
    常用知识点
    比较少用的格式
    git
    “没有用var声明的为全局变量”这种说法不准确
    类数组对象
    函数上下文的变量对象实例
    var a =10 与 a = 10的区别
    原型链与作用域链、执行上下文
    闭包的作用
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12852955.html
Copyright © 2011-2022 走看看