您的位置:首页 > 其它

hdu 5352 匈牙利(多重匹配)

2015-08-05 19:53 411 查看
由于实在不想拆点,写了个这样的代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <set>
using namespace std;

const int N = 5000;
bool g

;
bool g2

;
bool visit
;
set<int> mark
;
set<int>::iterator it;
int n, m, mm, k;

void dfs1( int u )
{
visit[u] = 1;
for ( int i = 1; i <= n; i++ )
{
if ( !visit[i] && g[u][i] )
{
dfs1(i);
}
}
}

int dfs2( int u )
{
for ( int i = mm; i >= 1; i-- )
{
if ( !visit[i] && g2[u][i] )
{
visit[i] = 1;
if ( mark[i].size() < k )
{
mark[i].insert(u);
return 1;
}
for ( it = mark[i].begin(); it != mark[i].end(); it++ )
{
if ( dfs2((*it)) )
{
mark[i].erase((*it));
mark[i].insert(u);
return 1;
}
}
}
}
return 0;
}

void hungary()
{
for ( int i = 1; i <= mm; i++ )
{
mark[i].clear();
}
int res = 0;
for ( int i = 1; i <= n; i++ )
{
memset( visit, 0, sizeof(visit) );
res += dfs2(i);
}
printf("%d\n", res);
for ( int i = 1; i <= mm; i++ )
{
printf("%d", mark[i].size());
if ( i != mm ) putchar(' ');
else putchar('\n');
}
}

int main ()
{
int t;
scanf("%d", &t);
while ( t-- )
{
scanf("%d%d%d", &n, &m, &k);
mm = 0;
memset( g, 0, sizeof(g) );
memset( g2, 0, sizeof(g2) );
while ( m-- )
{
int op;
scanf("%d", &op);
if ( op == 1 )
{
mm++;
int r;
scanf("%d", &r);
memset( visit, 0, sizeof(visit) );
dfs1(r);
for ( int j = 1; j <= n; j++ )
{
if ( visit[j] )
{
g2[j][mm] = 1;
}
}
}
else if ( op == 2 )
{
int u, v;
scanf("%d%d", &u, &v);
g[u][v] = g[v][u] = 1;
}
else if ( op == 3 )
{
int q;
scanf("%d", &q);
while ( q-- )
{
int u, v;
scanf("%d%d", &u, &v);
g[u][v] = g[v][u] = 0;
}
}
}
hungary();
}
return 0;
}


不过很可惜,这份代码是过不去的,具体原因我还没有找到。

只好乖乖拆点了...

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 501;
const int M = 7000;
const int K = 300000;
bool g

;
bool visit
;
int head[M];
int mark
;
int ans
;
int table
;
int n, m, k, p, e, ptr;

struct Edge
{
int v, next;
} edge[K];

void addEdge( int u, int v )
{
edge[e].v = v;
edge[e].next = head[u];
head[u] = e++;
}

void dfs1( int u )
{
visit[u] = 1;
table[ptr++] = u;
for ( int i = 1; i <= n; i++ )
{
if ( !visit[i] && g[u][i] )
{
dfs1(i);
}
}
}

int dfs2( int u )
{
for ( int i = head[u]; i != -1; i = edge[i].next )
{
int v = edge[i].v;
if ( !visit[v] )
{
visit[v] = 1;
if ( mark[v] == -1 || dfs2(mark[v]) )
{
mark[v] = u;
return 1;
}
}
}
return 0;
}

void hungary()
{
int res = 0;
memset( mark, -1, sizeof(mark) );
memset( ans, 0, sizeof(ans) );
for ( int i = p - 1; i >= 0; i-- )
{
for ( int j = i * k + 1; j <= ( i + 1 ) * k; j++ )
{
memset( visit, 0, sizeof(visit) );
if ( dfs2(j) )
{
res++;
ans[i]++;
}
}
}
printf("%d\n", res);
for ( int i = 0; i < p - 1; i++ )
{
printf("%d ", ans[i]);
}
printf("%d\n", ans[p - 1]);
}

int main ()
{
int t;
scanf("%d", &t);
while ( t-- )
{
scanf("%d%d%d", &n, &m, &k);
e = p = 0;
memset( head, -1, sizeof(head) );
memset( g, 0, sizeof(g) );
while ( m-- )
{
int op;
scanf("%d", &op);
if ( op == 1 )
{
int r;
scanf("%d", &r);
memset( visit, 0, sizeof(visit) );
ptr = 0;
dfs1(r);
for ( int j = 0; j < ptr; j++ )
{
for ( int y = p * k + 1; y <= ( p + 1 ) * k; y++ )
{
addEdge( y, table[j] );
}
}
p++;
}
else if ( op == 2 )
{
int u, v;
scanf("%d%d", &u, &v);
g[u][v] = g[v][u] = 1;
}
else if ( op == 3 )
{
int q;
scanf("%d", &q);
while ( q-- )
{
int u, v;
scanf("%d%d", &u, &v);
g[u][v] = g[v][u] = 0;
}
}
}
hungary();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: