POJ 1719 Shooting Contest

/* 给定一个 r*c 的格子矩阵,有C发子弹,每列格子有2个白色的方块,在1,2,3,...c 列上开枪打白色的格子,打到一个,那么这个白色方块所在的行就算打到了,求怎样打,才能把所有的行全部打到,如果全部打到而且有多余的列,那么这列随便打一个方块就可以了,按列的1,2,3,4......C的顺序,输出要打的行号。很明显的一个二分匹配,普通的二分匹配算法就行了。*/

#include <iostream>
#include 
<cstdio>
#include 
<algorithm>
#include 
<memory.h>
using namespace std;

#define INF 0x7ffffff
#define MAXN 4000
#define MAXE 20000

struct Edge{
    
int u,v;
    
int next;
}edge[MAXE];
int net[MAXN],visit[MAXN],pre[MAXN];
int nv,ne,index,r,c;
void add_edge(const int& u, const int& v)
{
    edge[index].next 
= net[u];
    net[u] 
= index;
    edge[index].v 
= v;
    edge[index].u 
= u;
    
++index;
}
int dfs(const int& u)
{
    
int i,v;
    
for(i = net[u]; i != -1; i = edge[i].next)
    {
        v 
= edge[i].v;
        
if(!visit[v])
        {
            visit[v] 
= 1;
            
if(-1 == pre[v] || dfs(pre[v]))
            {
                pre[v] 
= u;
                
return 1;
            }
        }
    }
    
return 0;
}
int main()
{
    
int i,j,k,h,tmp,sum,time,tmp1,tmp2,ans;
    scanf(
"%d",&time);
    
while(time--)
    {
        scanf(
"%d%d",&r,&c);
        index 
= ans = 0;
        memset(net,
-1,sizeof(net));
        memset(pre,
-1,sizeof(pre));
        
for(i = 1;i <= c; ++i)
        {
            scanf(
"%d%d",&tmp1,&tmp2);
            add_edge(tmp1,i);
            add_edge(tmp2,i);
            add_edge(i
+r,tmp1);
        }
        
if(c<r)
            ans 
= -1;
        
else
            
for(i = 1;i <= r; ++i)
            {
                memset(visit,
0,sizeof(visit));
                
if(dfs(i))
                    
++ans;
            }
        
if(ans < r)
            printf(
"NO\n");
        
else
        {
            
for(i = 1;i <= c; ++i)
            {
                
if(i != 1) printf(" ");
                
if(pre[i] != -1)
                    printf(
"%d",pre[i]);
                
else
                    printf(
"%d",edge[net[i+r]].v);
            }
            printf(
"\n");
        }
    }
    
return 0;
}

原文地址:https://www.cnblogs.com/lvpengms/p/1662748.html