您的位置:首页 > 其它

HDU 5352 (二分图匹配)

2016-07-29 21:21 330 查看

题目链接:点击这里

题意: n个被破坏的城市, m个操作, 一次最多修复k个点. 每次操作表示增加一些边, 或者删除一些边, 或者修复和某个点在相同联通分量里面的点. 问最多修复多少城市, 并且输出一种字典序最小的方案, 表示第i次修复多少城市.

如果把每一次修复都拆成k个点然后就很二分图了. 每一次修复的一个点和这次修复的连通分量的每一个点连边, 然后从后往前跑一次匈牙利就好了.

trick: 前向星TLE到死…vector过了…..

#include <bits/stdc++.h>
using namespace std;
#define maxn 100005

int G[233][233];
int n, m, k;
vector <int> g[maxn];
int head[maxn];
int year;
queue <int> q;
int pre[maxn], vis[233];
int num[maxn];

bool dfs (int u) {
int Max = g[u].size ();
for (int i = 0; i < Max; i++) {
int v = g[u][i];
if (!vis[v]) {
vis[v] = 1;
if (pre[v] == -1 || dfs (pre[v])) {
pre[v] = u;
return 1;
}
}
}
return 0;
}

int hungry () {
int ans = 0;
memset (pre, -1, sizeof pre);
for (int i = year-1; i >= 0; i--) {
memset (vis, 0, sizeof vis);
if (dfs (i))
ans++, num[i/k]++;
}
return ans;
}

void add_edge (int u, int v) {
g[u].push_back (v);
}

void bfs (int s) {
year;
memset (vis, 0, sizeof vis);
while (!q.empty ()) q.pop ();
q.push (s); vis[s] = 1;
while (!q.empty ()) {
int u = q.front (); q.pop ();
for (int i = 0; i < k; i++) {
add_edge (year+i, u);
}
for (int i = 1; i <= n; i++) if (!vis[i] && G[u][i]) {
q.push (i);
vis[i] = 1;
}
}
year += k;
}

int scan () {
char ch=' ';
while(ch<'0'||ch>'9')ch=getchar();
int x=0;
while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
return x;
}

int main () {
int t;
scanf ("%d", &t);
while (t--) {
scanf ("%d%d%d", &n, &m, &k);
for (int i = 0; i < m*k; i++) g[i].clear ();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
G[i][j] = 0;
}
year = 0;
for (int i = 1; i <= m; i++) {
int op, u, v;
op = scan ();
if (op == 1) {
u = scan ();
bfs (u);
}
else if (op == 2) {
u = scan (), v = scan ();
G[u][v] = G[v][u] = 1;
}
else if (op == 3) {
int num;
num = scan ();
while (num--) {
u = scan (), v = scan ();
G[u][v] = G[v][u] = 0;
}
}
}
for (int i = 0; i <= year/k; i++) num[i] = 0;
int ans = hungry ();
printf ("%d\n", ans);
for (int i = 0; i < year/k; i++) {
printf ("%d%c", num[i], (i == year/k-1 ? '\n' : ' '));
}
}
return 0;
}
/*
10
6 6 3
2 1 2
2 2 3
1 4
3 1 2 3
2 2 4
1 2
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: