这么裸的两个算法综合竟然错了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;
}