吐槽一下。。开这题的人需要有多大的勇气去读题。。。。。。给题目的长度给跪了。
题意。一大堆废话,总之就是一共有n个人,一个人能干statement或者testdata或者两样都能干,现在每一个人都一个rank,只有rank相差正好等于2的人才能配合(一个负责statement另一个负责testdata)求出最大搭配数,并且输出方案(左边statemenet,右边testdata)
题意解释完之后,马上就想到二分匹配。但这道题的二分图性质不是工作的性质。如果根据工作性质分类,那么都会的人无法处理。拆点会造成错误。这题的建图很强大。。。因为rank要正好相差2,那么rank模4小于2的两个人一定无法搭配,只有一个rank模4小于2的和大于等于2的人才能搭配,于是二分图性质出来了。。。。模4小于2的放左边,模4大于等于2的放右边,根据题意建图。。。。然后匹配。。。
题目不贴了。。。
地址:http://acm.timus.ru/problem.aspx?space=1&num=1721
#include <iostream>
#include <cstring>
#include <cmath>
#include <climits>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 1005;
const int maxm = 1000050;
struct edge
{
int to;
int next;
}edge[maxm];
int nx,ny;
int en;
int first[maxn];
int cx[maxn],cy[maxn];
int distx[maxn],disty[maxn];
int que[maxn],head,tail;
int ans;
void init()
{
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
memset(first,-1,sizeof(first));
en=0;
ans=0;
}
void add(int a, int b)
{
edge[en].to=b;
edge[en].next=first[a];
first[a]=en++;
}
bool bfs()
{
int i,j,k;
bool flag(0);
int h,t;
memset(distx,0,sizeof(distx));
memset(disty,0,sizeof(disty));
head=tail=0;
for(i=1;i<=nx;i++)
if (cx[i]==-1) que[tail++]=i;
while(head!=tail)
{
for(h=head,t=tail;h!=t;h=(h+1)%maxn)
{
i=que[h];
for(k=first[i];k!=-1;k=edge[k].next)
{
j=edge[k].to;
if(!disty[j])
{
disty[j]=distx[i] + 1;
if(cy[j]==-1)flag=1;
else
{
distx[cy[j]]=disty[j] + 1;
que[tail]=cy[j];
tail=(tail+1)%maxn;
}
}
}
}
head=t;
}
return flag;
}
bool dfs(int i)
{
int j, k;
for (k=first[i];k!=-1;k=edge[k].next)
{
j=edge[k].to;
if(disty[j]==distx[i]+1)
{
disty[j]=0;
if(cy[j]==-1||dfs(cy[j]))
{
cx[i]=j,cy[j]=i;
return 1;
}
}
}
return 0;
}
void Hopcroft_Karp()
{
int i,j;
while(bfs())
for(i=1;i<=nx;i++)
if(cx[i]==-1&&dfs(i))ans++;
}
struct node
{
char name[200];
int type,rank;
int no;
}data[1100];
char s[200];
int xx[1100],yy[1100];
int n;
int main()
{
while(~scanf("%d",&n))
{
init();
nx=ny=0;
for(int i=1;i<=n;i++)
{
scanf("%s",data[i].name);
scanf("%s",s);
if(strcmp(s,"anything")==0)
data[i].type=0;
else if(strcmp(s,"statements")==0)
data[i].type=1;
else
data[i].type=-1;
scanf("%d",&data[i].rank);
if(data[i].rank%4<2)
data[i].no=++nx,xx[nx]=i;
else
data[i].no=++ny,yy[ny]=i;
}
for(int i=1;i<=n;i++)
{
if(data[i].rank%4>=2) continue;
for(int j=1;j<=n;j++)
{
if(j==i) continue;
if(data[j].rank%4<2) continue;
if(abs(data[i].rank-data[j].rank)==2)
{
if(data[i].type+data[j].type!=-2 && data[i].type+data[j].type!=2)
{
add(data[i].no,data[j].no);
}
}
}
}
Hopcroft_Karp();
printf("%d\n",ans);
for(int i=1;i<=n;i++)
{
if(data[i].rank%4>=2) continue;
int u=data[i].no;
if(cx[u]==-1) continue;
int v=cx[u];
u=xx[u],v=yy[v];
int f,l;
f=l=100;
if(data[u].type==0 && data[v].type==0)
f=u,l=v;
else if(data[u].type==1)
f=u,l=v;
else if(data[u].type==-1)
f=v,l=u;
else if(data[v].type==1)
f=v,l=u;
else f=u,l=v;
printf("%s %s\n",data[f].name,data[l].name);
}
}
return 0;
}