强连通分量,看大神的题解才会写的....
http://www.cnblogs.com/kuangbin/p/3261157.html
数据量有点大,第一次Submit 2995ms过的,时限3000ms,差一点就TLE了。
#include#include #include #include #include using namespace std;const int maxn = 2000 + 10;int N, M;vector Cun[maxn];vector G[maxn];vector FG[maxn];int nx, ny, Time, Block;int g[maxn][maxn];int cx[maxn], cy[maxn];int mk[maxn];int flag[maxn], dfn[maxn], Belong[maxn];struct Point{ int id, dfn;} point[maxn];int Scan(){ int res = 0, ch, flag = 0; if ((ch = getchar()) == '-') //判断正负 flag = 1; else if (ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') res = res * 10 + ch - '0'; return flag ? -res : res;}bool cmp(const Point&a, const Point&b){ return a.dfn>b.dfn;}int path(int u){ for (int v = 1; v <= ny; v++) { if (g[u][v] && !mk[v]) { mk[v] = 1; if (cy[v] == -1 || path(cy[v])) { cx[u] = v; cy[v] = u; return 1; } } } return 0;}int MaxMatch(){ int res = 0; memset(cx, -1, sizeof(cx)); memset(cy, -1, sizeof(cy)); for (int i = 1; i <= nx; i++) { if (cx[i] == -1) { memset(mk, 0, sizeof(mk)); res = res + path(i); } } return res;}void dfs(int now){ flag[now] = 1; for (int i = 0; i 0)//王子有单身 { for (int j = M + 1; j <= M + B; j++) for (int i = 1; i <= N; i++) { g[i][j] = 1; G[i].push_back(j + nx); FG[j + nx].push_back(i); } } if (A>0) { for (int i = N + 1; i <= N + A; i++) for (int j = 1; j <= M; j++) { g[i][j] = 1; G[i].push_back(j + nx); FG[j + nx].push_back(i); } } for (int i = 1; i <= N; i++) for (int j = 0; j