您的位置:首页 > 其它

bzoj1143——CTSC2008祭祀river

2015-04-20 13:02 239 查看
传递闭包 + 二分图

#include <cstdio>
#include <cstring>

#define lp(i,j,k) for(int i = j;i <= k;++i)

int n,m,u,v,match;

int Link[210],vis[210];

struct edge {
int v,next;
}e[20010];
int head[210],cnt = -1;

bool acc[110][110];

int read_int () {
char c = getchar();
int re = 0;
for(;c < '0' || c > '9';c = getchar());
for(;c <= '9' && c >= '0';c = getchar())
re = re * 10 + c - '0';
return re;
}

void adde (int u,int v) {
e[++cnt].v = v;
e[cnt].next = head[u + n];
head[u + n] = cnt;
e[++cnt].v = u + n;
e[cnt].next = head[v];
head[v] = cnt;
}

bool find (int u) {
for(int i = head[u];i != -1;i = e[i].next) {
int v = e[i].v;
if(vis[v])
continue;
vis[v] = 1;
if(!Link[v] || find(Link[v])) {
Link[v] = u;
Link[u] = v;
return 1;
}
}
return 0;
}

int main () {
memset(head,-1,sizeof head);
n = read_int();
m = read_int();
lp(i,1,m)
acc[u = read_int()][v = read_int()] = 1;
lp(i,1,n)
lp(j,1,n)
if(acc[i][j])
lp(k,1,n)
acc[i][k] |= acc[i][j] & acc[j][k];
lp(i,1,n)
lp(j,1,n)
if(acc[i][j])
adde(i,j);
lp(i,1,n) {
memset(vis,0,sizeof vis);
vis[i] = 1;
if(find(i))
++match;
}
printf("%d\n",n - match);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: