poj1422 zoj1525 Air Raid 最小路径覆盖

来源:互联网 发布:苹果mac air办公用 编辑:程序博客网 时间:2024/06/06 00:18
/*题意:伞兵可以从任意点降落,每个点只可由一个伞兵到达,求遍历所有点至少需要多少伞兵题解:最小路径覆盖,拆点为二分图,求最大匹配x,n-x就是最小路径覆盖*/#include <cstdio>#include <iostream>#include<queue>#include<set>#include<ctime>#include<algorithm>#include<cmath>#include<vector>#include<map>#include<cstring>using namespace std;const int MAXN=509;int n,m;struct Edge{int v,next;}edge[MAXN*MAXN];int e;int first[MAXN];int Link[MAXN],vis[MAXN];void add(int u,int v){edge[e].v=v;edge[e].next=first[u];first[u]=e++;edge[e].v=u;edge[e].next=first[v];first[v]=e++;}void init(){int a,b;memset(first,-1,sizeof(first));e=0;scanf("%d%d",&n,&m);for(int i=0;i<m;i++){scanf("%d%d",&a,&b);add(a,b+n);}}bool can(int x){for(int k=first[x];k!=-1;k=edge[k].next){int v=edge[k].v;if(!vis[v]){vis[v]=true;if(Link[v]==-1||can(Link[v])){Link[v]=x;return true;}}}return false;}void solve(){int num=0;memset(Link,-1,sizeof(Link));for(int i=1;i<=n;i++){memset(vis,0,sizeof(vis));if(can(i))num++;}printf("%d\n",n-num);}int main(){int ca;scanf("%d",&ca);while(ca--){init();solve();}}