http://www.lydsy.com/JudgeOnline/problem.php?id=1143
题意:
思路:
二分图最大点独立集,首先用floyd判断一下可达情况。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,tot; int mp[105][105],mark[105],head[105]; bool vis[105]; struct node { int v,next; }e[1005]; void addEdge(int u,int v) { e[tot].v = v; e[tot].next = head[u]; head[u] = tot++; } void floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]); } bool match(int u) { for(int i=head[u];i!=-1;i=e[i].next) { int v = e[i].v; if(!vis[v]) { vis[v] = true; if(mark[v]==-1 || match(mark[v])) { mark[v] = u; return true; } } } return false; } int main() { tot = 0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); mp[u][v] = 1; } floyd(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(mp[i][j]) addEdge(i,j); } } int sum = 0; memset(mark,-1,sizeof(mark)); for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(match(i)) sum++; } printf("%d ",n-sum); }