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;
}
#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;
}