【USACO】wormholes 【暴力】
题意:给出2K个平面上的点,给它们一一配对,问有多少种配对方法使得存在从某个点一直向右走会陷在循环里(K<=6)
思路:由于k很小,配对方法的话暴力枚举,然后判环,判环时需要注意的是一条直线上的四个点1,2,3,4 其中1和3配对,2和4配对,可以发现它不构成环,详见代码
/*{
ID:a4298442
PROB:wormhole
LANG:C++
}
*/
#include <stdio.h>
#include <iostream>
#include<fstream>
#include <string.h>
#include <algorithm>
#define maxn 1000
using namespace std;
ifstream fin("wormhole.in");
ofstream fout("wormhole.out");
struct T{int x;int y;}p[maxn];
int ans=0,g[maxn],match[maxn],n,visit[maxn];
int cmp(T x,T y){
return (x.y<y.y || ((x.y==y.y)&&(x.x<y.x)));
}
int circle(int u)
{
int vis[100]={0},v=g[u];
vis[u]=1;
while(v!=0){
u=match[v];
if(!u)return 0;v=g[u];
if(vis[u])return 1;vis[u]=1;
}
return 0;
}
void dfs(int k,int u,int num){
if(num==n){
for(int i=1;i<=n;i++)if(circle(i)){ans++;break;}
return;
}
visit[k]=1;
for(int i=(u==0)?k+1:1;i<=n;i++)if(visit[i]==0){
if(u==0){g[i]=k;g[k]=i;}
dfs(i,u^1,num+1);
if(u==0)g[i]=g[k]=0;else break;
}
visit[k]=0;
}
int main(){
fin>>n;
for(int i=1;i<=n;i++)fin>>p[i].x>>p[i].y;
sort(p+1,p+1+n,cmp);
for(int i=2;i<=n;i++)if(p[i].y==p[i-1].y)match[i-1]=i;
dfs(1,0,1);
fout<<ans<<endl;
return 0;
}