题意:Ri爷的题,写了50分暴力,,,然后想搞退流无果,,被Cena咖啡了,,就不多说啥了吧
过了大数据,,,貌似跑的很慢,,,是不是常数太大?
知识点:tarjan强连通分量,二分图匹配
idea很好,,,由增广路推倒出做法,将匹配边反向形成强连通分量是关键
相关:LA 2966 HDU 4685(加强版)
未完待续
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#define N 2000
using namespace std;
struct edge{ int nxt,point,v;};
edge e[((N*N)<<1)+5];
int tot[(N<<1)+5],n,a[N+5][N+5],link[(N<<1)+5],time,dfn[(N<<1)+5],low[(N<<1)+5],
stack[(N<<1)+5],num,color[(N<<1)+5],cnt;
bool vis[(N<<1)+5],in[(N<<1)+5];
inline void addedge(int u1,int v1){
e[++cnt].nxt = e[u1].point; e[u1].point = cnt; e[cnt].v = v1;}
inline void insert(int u1,int v1){ addedge(u1,v1); addedge(v1,u1);}
inline int getnum(){
char c; int num;
while (!isdigit(c = getchar()));
num = c - '0';
while (isdigit(c = getchar())) num = 10*num +c -'0';
return num;
}
void init(){
n = getnum(); cnt = 0;
for (int i = 1;i <= n; ++i){
a[i][0] = getnum();
for (int j = 1;j <= a[i][0]; ++j) a[i][j] = getnum(),insert(i,a[i][j]+n);
sort(a[i]+1,a[i]+a[i][0]+1);
}
}
inline bool dfs1(int x){
for (int p = e[x].point; p ;p = e[p].nxt)
{
int t = e[p].v;
if (!vis[t]){
vis[t] = 1;
if (!link[t]||dfs1(link[t])){
link[t] = x;
return 1;}
}
}
return 0;
}
void match_it(){
memset(link,0,sizeof(link));
for (int i = 1;i <= n+n; ++i){
memset(vis,0,sizeof(vis));
dfs1(i);
}
}
void make_it(){
memset(e,0,sizeof(e));
for (int i = 1;i <= n; ++i)
for (int j = 1;j <= a[i][0]; ++j){
if (link[a[i][j]+n]==i) addedge(a[i][j]+n,i);
addedge(i,a[i][j]+n);}
}
inline void pop_it(int x){
while (stack[num] != x) in[stack[num]] = 0, color[stack[num--]] = x;
in[x] = 0; num--;
}
inline void dfs2(int x){
dfn[x] = low[x] = ++time;
stack[++num] = x; in[x] = 1;
for (int p = e[x].point;p ; p = e[p].nxt)
if (!vis[e[p].v]) {
vis[e[p].v] = 1;
dfs2(e[p].v);
low[x] = min(low[x],low[e[p].v]);}
else if (in[e[p].v]) low[x] = min(low[x],dfn[e[p].v]);
if (dfn[x] == low[x]) pop_it(x);
}
void DO_IT(){
match_it();
make_it();
time = 0; num = 0;
memset(vis,0,sizeof(vis));
for (int i = 1;i <= n+n; ++i) color[i] = i;
for (int i = 1;i <= n+n; ++i)
if (!vis[i]) dfs2(i);
}
void print(){
memset(tot,0,sizeof(tot));
for (int i = 1;i <= n; ++i)
for (int j = 1;j <= a[i][0]; ++j)
if (color[i]==color[a[i][j]+n]) tot[i] ++;
for (int i = 1;i <= n; ++i){
printf("%d ",tot[i]);
for (int j = 1;j <= a[i][0]; ++j)
if (color[i]==color[a[i][j]+n]) printf("%d ",a[i][j]);
puts("");}
}
int main(){
freopen("quest.in","r",stdin);
freopen("quest.out","w",stdout);
init();
DO_IT();
print();
fclose(stdin); fclose(stdout);
return 0;
}