刚开始想得难了,打算把二分图建出来,把顶点分开!其实不用,直接对原图求最大匹配,然后除以2.
这里刚开始敲模板,把下标弄错了,题目是从0开始,我直接从1开始!还有一件事情,一定一定要记得,就是给bmap初始化!!!!很重要,至关重要的!!!
代码:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1515;
const int INF = 0x3fffffff;
int n, bmap[N][N], cy[N], cx[N];
int dy[N], dx[N], dis;
bool used[N];
bool search()
{
queue <int> Q;
dis = INF;
memset(dx, -1, sizeof(dx));
memset(dy, -1, sizeof(dy));
for ( int i = 0; i < n; ++i )
if ( cx[i] == -1 ) {
Q.push(i);
dx[i] = 0;
}
while ( !Q.empty() ) {
int u = Q.front();
Q.pop();
if ( dx[u] > dis ) break;
for ( int v = 0; v < n; ++v )
if ( bmap[u][v] && dy[v] == -1 ) {
dy[v] = dx[u] + 1;
if ( cy[v] == -1 ) dis = dy[v];
else {
dx[cy[v]] = dy[v]+1;
Q.push( cy[v] );
}
}
}
return dis != INF;
}
bool dfs( int u )
{
for ( int v = 0; v < n; ++v ) if ( bmap[u][v] && !used[v] && dx[u]+1 == dy[v] ) {
used[v] = 1;
if ( cy[v] != -1 && dy[v] == dis ) continue;
if ( cy[v] == -1 || dfs( cy[v] ) ) {
cy[v] = u;
cx[u] = v;
return 1;
}
}
return 0;
}
int Hmatch()
{
int res = 0;
memset(cy, -1, sizeof(cy));
memset(cx, -1, sizeof(cx));
while ( search() ) {
memset( used, 0, sizeof(used));
for ( int i = 0; i < n; ++i ) if ( cx[i] == -1 ) {
res += dfs(i);
}
}
return res;
}
int main()
{
while ( scanf("%d", &n) != EOF ) {
memset(bmap, 0, sizeof(bmap));
for ( int i = 0; i < n; ++i ) {
int u, v, k;
scanf("%d:(%d)", &u, &k);
while( k-- ) {
scanf("%d", &v);
bmap[u][v] = bmap[v][u] = 1;
}
}
printf("%d\n", Hmatch()/2);
}
}