您的位置:首页 > 其它

伤不起的 强连通+二分匹配 hdu 3861

2011-07-20 20:57 369 查看
这么裸的两个算法综合竟然错了15把

,重新写了一遍 ,终于A了,伤不起啊.....
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include <vector>
using namespace std;

#define MAXN 100010
//////////////强连通////////////////
vector<int>mat[MAXN];////原图
int id[MAXN/2], pre[MAXN/2];
int low[MAXN/2], s[MAXN/2];
int stop, cnt, scnt;

void tarjan(int v, int n){
int t, minc = low[v] = pre[v] = cnt++;
vector<int>::iterator pv;
s[stop++] = v;
for (pv = mat[v].begin(); pv != mat[v].end(); ++pv){
if (-1 == pre[*pv])
tarjan(*pv, n);
if (low[*pv] < minc)
minc = low[*pv];
}

if (minc < low[v]){
low[v] = minc;
return;
}

do{
id[t = s[--stop]] = scnt;
low[t] = n;
}while (t != v);
++scnt;
}

/////////////二分匹配/////////
vector<int>new_mat[MAXN];//新图
bool flag[MAXN];
int qian[MAXN];

bool dfs(int u){
for (int i = 0; i < new_mat[u].size(); i++){
int v = new_mat[u][i];
if (flag[v])
continue;
flag[v] = 1;
if (qian[v] == -1 || dfs(qian[v])){
qian[v] = u;
return true;
}
}
return false;
}

int MaxMatch(){
int i , ans = 0;
memset(qian, -1, sizeof(qian));
for (i = 0; i < scnt; i++){
memset(flag, false, sizeof(flag));
if (dfs(i))
ans++;
}
return ans;
}
///////////////////////////

int UU[MAXN], VV[MAXN];

int main()
{
int T;
int n, m;

scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);

for (int i = 0; i <= n; i++)
mat[i].clear();

for (int i = 0; i < m; i++){
scanf("%d%d", &UU[i], &VV[i]);
UU[i]--;
VV[i]--;
mat[UU[i]].push_back(VV[i]);
}

//////强连通///////
stop = cnt = scnt = 0;
memset(pre, -1, sizeof(pre));

for (int i = 0; i < n; i++){
if (-1 == pre[i])
tarjan(i, n);
}

if (scnt == 1){
printf("1\n");
continue;
}
/*///////
printf("每个点所属的强连通编号: ");
for (int i = 0; i < n; i++)
printf("%d = %d ", i, id[i]);
printf("\n");
///////*/

////////////二分匹配/////////
/*建图*/
for (int i = 0; i < scnt*2; i++)
new_mat[i].clear();

for (int i = 0; i < m; i++){
int fa_u = id[UU[i]];
int fa_v = id[VV[i]];
if (fa_u != fa_v){
new_mat[fa_u].push_back(fa_v+scnt);
}
}
printf("%d\n", scnt - MaxMatch());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: