这题刚上来反应像是二分图但是,自己水平太渣又感觉和之前的二分不同,但是的确时二分图(- -! 一变化就不认识了).注意此题的储存方式用前向星,对于二分图都是点与点之间的关系所以将直线和曲线都要转化为两种集合的形式.那么一种是比值的形式一种是,半径的形式,毕竟不是规律的点对点,所以借助map容器来进行将浮点转化为整数的形式
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <map>
#define inf 0x3f3f3f3f
#define Max 20010
using namespace std;
map<double,int>m1;
map<int,int>m2;
struct node
{
int to,next;
}q[Max];
int head[Max],linkmap[Max],cnt,cnt1,cnt2;
bool vis[Max];
int dfs(int v)
{
for(int i=head[v];i!=-1;i=q[i].next)
{
int u=q[i].to;
if(!vis[u ])
{
vis[u ]=true;
if(linkmap[u ]==-1||dfs(linkmap[u]))
{
linkmap[u]=v;
return 1;
}
}
}
return 0;
}
void solve()
{
int ans=0;
for(int i=0;i<cnt1;i++)
{
memset(vis,false,sizeof(vis));
ans+=dfs(i);
}
printf("%d\n",ans);
}
void add(int x,int y)
{
q[cnt].to=y;
q[cnt].next=head[x];
head[x]=cnt++;
}
int main()
{
int n,m,i,j,t,k,x,y,z;double tmp;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
m1.clear();m2.clear();
memset(head,-1,sizeof(head));
memset(linkmap,-1,sizeof(linkmap) );
cnt1=0,cnt2=n;cnt=0;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
tmp=z*1.0/y;
if(m2.find(x)==m2.end())
m2[x]=cnt1++;
if(m1.find(tmp)==m1.end())//对于在map中已经有的元素(map可以进行查找)不必再进行进容器因为都是属于一类的.
m1[tmp]=cnt2++;
add(m2[x],m1[tmp]);//将两点进行合并写成前向星
}
solve();
}
return 0;
}