题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1845
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <cmath>
#define MAXN 5001
using namespace std;
int nx,ny,distx[MAXN],disty[MAXN];
int visited[MAXN],mx[MAXN],my[MAXN];
vector<int> graphics[MAXN];
queue<int> Q;
int Scan()
{
char ch;
int ret=0;
while((ch=getchar())<'0'||ch>'9');
while(ch>='0'&&ch<='9')
{
ret=ret*10+(ch-'0');
ch=getchar();
}
return ret;
}
int find(int u)
{//寻找增广路
int i,temp;
for(i=0;i<graphics[u].size();++i)
{
temp=graphics[u][i];
if(!visited[temp]&&(disty[temp]==distx[u]+1))
{
visited[temp]=1;
if(!my[temp]||find(my[temp]))
{
mx[u]=temp;
my[temp]=u;
return 1;
}
}
}
return 0;
}
int search()
{
int temp,u,flag=0;
memset(distx,0,sizeof(distx));
memset(disty,0,sizeof(disty));
while(!Q.empty())
Q.pop();
for(int i=1;i<=nx;++i)
{
if(!mx[i])
Q.push(i);
}
while(!Q.empty())
{
u=Q.front();
Q.pop();
for(int i=0;i<graphics[u].size();++i)
{
temp=graphics[u][i];
if(!disty[temp])
{
disty[temp]=distx[u]+1;
if(my[temp])
{
distx[my[temp]]=disty[temp]+1;
Q.push(my[temp]);
}
else
flag=1;
}
}
}
return flag;
}
int matching()
{
int ans=0;
memset(mx,0,sizeof(mx));
memset(my,0,sizeof(my));
while(search())
{
memset(visited,0,sizeof(visited));
for(int i=1;i<=nx;++i)
if(!mx[i]&&find(i))
ans++;
}
return ans;
}
int main()
{
int n,u,v,sum,test,N;
scanf("%d",&test);
while(test--)
{
scanf("%d",&n);
N=(n>>1)*3;
for(int i=0;i<=n;++i)
graphics[i].clear();
while(N--)
{
//scanf("%d %d",&u,&v);
u=Scan();
v=Scan();
graphics[u].push_back(v); //用邻接表
graphics[v].push_back(u); //建双向图
}
nx=ny=n;
sum=matching();
printf("%d\n",sum/2);
}
return 0;
}
#include<stdio.h>
int main()
{
int t,n,i,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n*3/2;i++)
scanf("%d%d",&x,&y);
printf("%d\n",n/2);
}
return 0;
}